diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index 022218a2..bd2c38a1 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -169,7 +169,9 @@ public: std::optional FGHUDPrevious; bool FGOnlyGenerated = false; bool FGChanged = false; - bool SGChanged = false; + bool SCChanged = false; + bool SkipHeapCapture = false; + // nvngx init parameters unsigned long long NVNGX_ApplicationId = 1337; diff --git a/OptiScaler/NVNGX_DLSS_Dx12.cpp b/OptiScaler/NVNGX_DLSS_Dx12.cpp index ee40cf1a..f41a2f14 100644 --- a/OptiScaler/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/NVNGX_DLSS_Dx12.cpp @@ -22,7 +22,6 @@ #include #include "depth_upscale/DU_Dx12.h" -#include "format_transfer/FT_Dx12.h" static PfnFfxCreateContext _createContext = nullptr; static PfnFfxDestroyContext _destroyContext = nullptr; @@ -31,7 +30,6 @@ static PfnFfxQuery _query = nullptr; static PfnFfxDispatch _dispatch = nullptr; static UINT64 fgLastFrameTime = 0; static DU_Dx12* DepthUpscaler = nullptr; -static FT_Dx12* FormatTransfer = nullptr; static UINT64 fgTarget = 0; static ID3D12Device* D3D12Device = nullptr; @@ -1354,7 +1352,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom createFg.header.pNext = &backendDesc.header; Config::Instance()->dxgiSkipSpoofing = true; + Config::Instance()->SkipHeapCapture = true; ffxReturnCode_t retCode = _createContext(&ImGuiOverlayDx::fgContext, &createFg.header, nullptr); + Config::Instance()->SkipHeapCapture = false; Config::Instance()->dxgiSkipSpoofing = false; LOG_INFO(" FG _createContext result: {0:X}", retCode); } diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index c3eb321b..3881f661 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -208,8 +208,6 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\ - - @@ -297,7 +295,6 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\ - diff --git a/OptiScaler/backends/fsr2/FSR2Feature_Dx11On12.cpp b/OptiScaler/backends/fsr2/FSR2Feature_Dx11On12.cpp index 0b22045a..35b15300 100644 --- a/OptiScaler/backends/fsr2/FSR2Feature_Dx11On12.cpp +++ b/OptiScaler/backends/fsr2/FSR2Feature_Dx11On12.cpp @@ -645,7 +645,9 @@ bool FSR2FeatureDx11on12::InitFSR2(const NVSDK_NGX_Parameter* InParameters) LOG_DEBUG("ffxFsr2ContextCreate!"); + Config::Instance()->SkipHeapCapture = true; auto ret = ffxFsr2ContextCreate(&_context, &_contextDesc); + Config::Instance()->SkipHeapCapture = false; if (ret != FFX_OK) { diff --git a/OptiScaler/backends/fsr2/FSR2Feature_Dx12.cpp b/OptiScaler/backends/fsr2/FSR2Feature_Dx12.cpp index 81b08a2b..a25a3118 100644 --- a/OptiScaler/backends/fsr2/FSR2Feature_Dx12.cpp +++ b/OptiScaler/backends/fsr2/FSR2Feature_Dx12.cpp @@ -592,7 +592,9 @@ bool FSR2FeatureDx12::InitFSR2(const NVSDK_NGX_Parameter* InParameters) LOG_DEBUG("ffxFsr2ContextCreate!"); + Config::Instance()->SkipHeapCapture = true; auto ret = ffxFsr2ContextCreate(&_context, &_contextDesc); + Config::Instance()->SkipHeapCapture = false; if (ret != FFX_OK) { diff --git a/OptiScaler/backends/fsr2_212/FSR2Feature_Dx11On12_212.cpp b/OptiScaler/backends/fsr2_212/FSR2Feature_Dx11On12_212.cpp index d3ac100d..e03342e7 100644 --- a/OptiScaler/backends/fsr2_212/FSR2Feature_Dx11On12_212.cpp +++ b/OptiScaler/backends/fsr2_212/FSR2Feature_Dx11On12_212.cpp @@ -645,7 +645,9 @@ bool FSR2FeatureDx11on12_212::InitFSR2(const NVSDK_NGX_Parameter* InParameters) LOG_DEBUG("ffxFsr2ContextCreate!"); + Config::Instance()->SkipHeapCapture = true; auto ret = Fsr212::ffxFsr2ContextCreate212(&_context, &_contextDesc); + Config::Instance()->SkipHeapCapture = false; if (ret != Fsr212::FFX_OK) { diff --git a/OptiScaler/backends/fsr2_212/FSR2Feature_Dx12_212.cpp b/OptiScaler/backends/fsr2_212/FSR2Feature_Dx12_212.cpp index be5d186a..fcebb84b 100644 --- a/OptiScaler/backends/fsr2_212/FSR2Feature_Dx12_212.cpp +++ b/OptiScaler/backends/fsr2_212/FSR2Feature_Dx12_212.cpp @@ -593,7 +593,9 @@ bool FSR2FeatureDx12_212::InitFSR2(const NVSDK_NGX_Parameter* InParameters) LOG_DEBUG("ffxFsr2ContextCreate!"); + Config::Instance()->SkipHeapCapture = true; auto ret = Fsr212::ffxFsr2ContextCreate212(&_context, &_contextDesc); + Config::Instance()->SkipHeapCapture = false; if (ret != Fsr212::FFX_OK) { diff --git a/OptiScaler/backends/fsr31/FSR31Feature_Dx11On12.cpp b/OptiScaler/backends/fsr31/FSR31Feature_Dx11On12.cpp index 983ef340..96945e78 100644 --- a/OptiScaler/backends/fsr31/FSR31Feature_Dx11On12.cpp +++ b/OptiScaler/backends/fsr31/FSR31Feature_Dx11On12.cpp @@ -726,7 +726,10 @@ bool FSR31FeatureDx11on12::InitFSR3(const NVSDK_NGX_Parameter* InParameters) backendDesc.header.pNext = &ov.header; LOG_DEBUG("_createContext!"); + + Config::Instance()->SkipHeapCapture = true; auto ret = _createContext(&_context, &_contextDesc.header, NULL); + Config::Instance()->SkipHeapCapture = false; if (ret != FFX_API_RETURN_OK) { diff --git a/OptiScaler/backends/fsr31/FSR31Feature_Dx12.cpp b/OptiScaler/backends/fsr31/FSR31Feature_Dx12.cpp index 425c5f9f..d350968f 100644 --- a/OptiScaler/backends/fsr31/FSR31Feature_Dx12.cpp +++ b/OptiScaler/backends/fsr31/FSR31Feature_Dx12.cpp @@ -678,7 +678,10 @@ bool FSR31FeatureDx12::InitFSR3(const NVSDK_NGX_Parameter* InParameters) backendDesc.header.pNext = &ov.header; LOG_DEBUG("_createContext!"); + + Config::Instance()->SkipHeapCapture = true; auto ret = _createContext(&_context, &_contextDesc.header, NULL); + Config::Instance()->SkipHeapCapture = false; if (ret != FFX_API_RETURN_OK) { diff --git a/OptiScaler/backends/xess/XeSSFeature.cpp b/OptiScaler/backends/xess/XeSSFeature.cpp index 5a7a5a92..0a6b4d5a 100644 --- a/OptiScaler/backends/xess/XeSSFeature.cpp +++ b/OptiScaler/backends/xess/XeSSFeature.cpp @@ -221,7 +221,9 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa if (ret == XESS_RESULT_SUCCESS) { CD3DX12_HEAP_DESC bufferHeapDesc(xessProps.tempBufferHeapSize, D3D12_HEAP_TYPE_DEFAULT); + Config::Instance()->SkipHeapCapture = true; hr = device->CreateHeap(&bufferHeapDesc, IID_PPV_ARGS(&_localBufferHeap)); + Config::Instance()->SkipHeapCapture = false; if (SUCCEEDED(hr)) { @@ -229,7 +231,9 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa {D3D12_HEAP_TYPE_DEFAULT, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_UNKNOWN, 0, 0}, 0, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES }; + Config::Instance()->SkipHeapCapture = true; hr = device->CreateHeap(&textureHeapDesc, IID_PPV_ARGS(&_localTextureHeap)); + Config::Instance()->SkipHeapCapture = false; if (SUCCEEDED(hr)) { @@ -264,6 +268,7 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa if (Config::Instance()->BuildPipelines.value_or(true)) { LOG_DEBUG("xessD3D12BuildPipelines!"); + Config::Instance()->SkipHeapCapture = true; ID3D12Device1* device1; if (FAILED(device->QueryInterface(IID_PPV_ARGS(&device1)))) @@ -300,6 +305,8 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa if (device1 != nullptr) device1->Release(); + Config::Instance()->SkipHeapCapture = false; + if (ret != XESS_RESULT_SUCCESS) { LOG_ERROR("xessD3D12BuildPipelines error: {0}", ResultToString(ret)); @@ -315,7 +322,9 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa LOG_ERROR("xessSelectNetworkModel result: {0}", ResultToString(ret)); } + Config::Instance()->SkipHeapCapture = true; ret = XeSSProxy::D3D12Init()(_xessContext, &xessParams); + Config::Instance()->SkipHeapCapture = false; Config::Instance()->dxgiSkipSpoofing = false; diff --git a/OptiScaler/bias/Bias_Dx12.cpp b/OptiScaler/bias/Bias_Dx12.cpp index fc114df6..d60dd59f 100644 --- a/OptiScaler/bias/Bias_Dx12.cpp +++ b/OptiScaler/bias/Bias_Dx12.cpp @@ -392,6 +392,8 @@ Bias_Dx12::Bias_Dx12(std::string InName, ID3D12Device* InDevice) : _name(InName) heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + Config::Instance()->SkipHeapCapture = true; + auto hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[0])); if (FAILED(hr)) @@ -402,6 +404,8 @@ Bias_Dx12::Bias_Dx12(std::string InName, ID3D12Device* InDevice) : _name(InName) hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[1])); + Config::Instance()->SkipHeapCapture = false; + if (FAILED(hr)) { LOG_ERROR("[{0}] CreateDescriptorHeap[1] error {1:x}", _name, (unsigned int)hr); diff --git a/OptiScaler/depth_upscale/DU_Dx12.cpp b/OptiScaler/depth_upscale/DU_Dx12.cpp index 3e7ca761..7eb38aed 100644 --- a/OptiScaler/depth_upscale/DU_Dx12.cpp +++ b/OptiScaler/depth_upscale/DU_Dx12.cpp @@ -327,6 +327,8 @@ DU_Dx12::DU_Dx12(std::string InName, ID3D12Device* InDevice) : _name(InName), _d heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + Config::Instance()->SkipHeapCapture = true; + auto hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[0])); if (FAILED(hr)) @@ -345,6 +347,8 @@ DU_Dx12::DU_Dx12(std::string InName, ID3D12Device* InDevice) : _name(InName), _d hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[2])); + Config::Instance()->SkipHeapCapture = false; + if (FAILED(hr)) { LOG_ERROR("[{0}] CreateDescriptorHeap[2] error {1:x}", _name, hr); diff --git a/OptiScaler/format_transfer/FT_Common.h b/OptiScaler/format_transfer/FT_Common.h deleted file mode 100644 index 22bb0664..00000000 --- a/OptiScaler/format_transfer/FT_Common.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once -#include "../pch.h" -#include -#include - -inline static std::string ftR10G10B10A2Code = R"( -Texture2D SourceTexture : register(t0); -RWTexture2D DestinationTexture : register(u0); // R10G10B10A2_UNORM destination texture - -// Shader to perform the conversion -[numthreads(512, 1, 1)] -void CSMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - // Read from the source texture - float4 srcColor = SourceTexture.Load(int3(dispatchThreadID.xy, 0)); - - // Clamp color channels to [0, 1] range, as R10G10B10A2_UNORM is normalized - srcColor = saturate(srcColor); // Ensures all values are between 0 and 1 - - // Convert each channel to its corresponding bit range - uint R = (uint)(srcColor.r * 1023.0f); // 10 bits for Red - uint G = (uint)(srcColor.g * 1023.0f); // 10 bits for Green - uint B = (uint)(srcColor.b * 1023.0f); // 10 bits for Blue - uint A = (uint)(srcColor.a * 3.0f); // 2 bits for Alpha - - // Pack the values into a single 32-bit unsigned int - uint packedColor = R | G << 10 | B << 20 | A << 30; - - // Write the packed color to the destination texture - DestinationTexture[dispatchThreadID.xy] = packedColor; -} -)"; - -inline static std::string ftR8G8B8A8Code = R"( -Texture2D SourceTexture : register(t0); -RWTexture2D DestinationTexture : register(u0); // R8G8B8A8_UNORM destination texture - -// Shader to perform the conversion -[numthreads(512, 1, 1)] -void CSMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - // Read from the source texture - float4 srcColor = SourceTexture.Load(int3(dispatchThreadID.xy, 0)); - - // Clamp color channels to [0, 1] range, as R8G8B8A8_UNORM is normalized - srcColor = saturate(srcColor); // Ensures all values are between 0 and 1 - - // Convert each channel to its corresponding bit range - uint R = (uint)(srcColor.r * 255.0f); // 8 bits for Red - uint G = (uint)(srcColor.g * 255.0f); // 8 bits for Green - uint B = (uint)(srcColor.b * 255.0f); // 8 bits for Blue - uint A = (uint)(srcColor.a * 255.0f); // 8 bits for Alpha - - // Pack the values into a single 32-bit unsigned int - uint packedColor = R | G << 8 | B << 16 | A << 24; - - // Write the packed color to the destination texture - DestinationTexture[dispatchThreadID.xy] = packedColor; -} -)"; - -inline static std::string ftB8G8R8A8Code = R"( -Texture2D SourceTexture : register(t0); -RWTexture2D DestinationTexture : register(u0); // R8G8B8A8_UNORM destination texture - -// Shader to perform the conversion -[numthreads(512, 1, 1)] -void CSMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - // Read from the source texture - float4 srcColor = SourceTexture.Load(int3(dispatchThreadID.xy, 0)); - - // Clamp color channels to [0, 1] range, as R8G8B8A8_UNORM is normalized - srcColor = saturate(srcColor); // Ensures all values are between 0 and 1 - - // Convert each channel to its corresponding bit range - uint R = (uint)(srcColor.r * 255.0f); // 8 bits for Red - uint G = (uint)(srcColor.g * 255.0f); // 8 bits for Green - uint B = (uint)(srcColor.b * 255.0f); // 8 bits for Blue - uint A = (uint)(srcColor.a * 255.0f); // 8 bits for Alpha - - // Pack the values into a single 32-bit unsigned int - uint packedColor = B | R << 8 | G << 16 | A << 24; - - // Write the packed color to the destination texture - DestinationTexture[dispatchThreadID.xy] = packedColor; -} -)"; - - -inline static ID3DBlob* FT_CompileShader(const char* shaderCode, const char* entryPoint, const char* target) -{ - ID3DBlob* shaderBlob = nullptr; - ID3DBlob* errorBlob = nullptr; - - HRESULT hr = D3DCompile(shaderCode, strlen(shaderCode), nullptr, nullptr, nullptr, entryPoint, target, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &shaderBlob, &errorBlob); - - if (FAILED(hr)) - { - LOG_ERROR("error while compiling shader"); - - if (errorBlob) - { - LOG_ERROR("error while compiling shader : {0}", (char*)errorBlob->GetBufferPointer()); - errorBlob->Release(); - } - - if (shaderBlob) - shaderBlob->Release(); - - return nullptr; - } - - if (errorBlob) - errorBlob->Release(); - - return shaderBlob; -} \ No newline at end of file diff --git a/OptiScaler/format_transfer/FT_Dx12.cpp b/OptiScaler/format_transfer/FT_Dx12.cpp deleted file mode 100644 index b8b3cd38..00000000 --- a/OptiScaler/format_transfer/FT_Dx12.cpp +++ /dev/null @@ -1,423 +0,0 @@ -#include "FT_Dx12.h" - -#include "../Config.h" - -inline static DXGI_FORMAT TranslateTypelessFormats(DXGI_FORMAT format) -{ - switch (format) { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case DXGI_FORMAT_R32G32B32_TYPELESS: - return DXGI_FORMAT_R32G32B32_FLOAT; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - return DXGI_FORMAT_R10G10B10A2_UINT; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return DXGI_FORMAT_B8G8R8A8_UNORM; - case DXGI_FORMAT_R16G16_TYPELESS: - return DXGI_FORMAT_R16G16_FLOAT; - case DXGI_FORMAT_R32G32_TYPELESS: - return DXGI_FORMAT_R32G32_FLOAT; - case DXGI_FORMAT_R32G8X24_TYPELESS: - return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_R32_FLOAT; - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - default: - return format; - } -} - -static bool CreateComputeShader(ID3D12Device* device, ID3D12RootSignature* rootSignature, ID3D12PipelineState** pipelineState, ID3DBlob* shaderBlob) -{ - D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {}; - psoDesc.pRootSignature = rootSignature; - psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; - psoDesc.CS = CD3DX12_SHADER_BYTECODE(shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize()); - - HRESULT hr = device->CreateComputePipelineState(&psoDesc, __uuidof(ID3D12PipelineState*), (void**)pipelineState); - - if (FAILED(hr)) - { - LOG_ERROR("CreateComputePipelineState error {0:x}", hr); - return false; - } - - return true; -} - -bool FT_Dx12::CreateBufferResource(ID3D12Device* InDevice, ID3D12Resource* InSource, D3D12_RESOURCE_STATES InState) -{ - if (InDevice == nullptr || InSource == nullptr) - return false; - - LOG_FUNC(); - - D3D12_RESOURCE_DESC texDesc = InSource->GetDesc(); - - if (_buffer != nullptr) - { - auto bufDesc = _buffer->GetDesc(); - - if (bufDesc.Width != texDesc.Width || bufDesc.Height != texDesc.Height || bufDesc.Format != format) - { - _buffer->Release(); - _buffer = nullptr; - } - else - return true; - } - - LOG_DEBUG("[{0}] Start!", _name); - - LOG_INFO("Texture Format: {}", (UINT)texDesc.Format); - - D3D12_HEAP_PROPERTIES heapProperties; - D3D12_HEAP_FLAGS heapFlags; - HRESULT hr = InSource->GetHeapProperties(&heapProperties, &heapFlags); - - if (hr != S_OK) - { - LOG_ERROR("[{0}] GetHeapProperties result: {1:x}", _name.c_str(), hr); - return false; - } - - texDesc.Format = format; - texDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS | D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS; - - hr = InDevice->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &texDesc, InState, nullptr, IID_PPV_ARGS(&_buffer)); - - if (hr != S_OK) - { - LOG_ERROR("[{0}] CreateCommittedResource result: {1:x}", _name, hr); - return false; - } - - - _buffer->SetName(L"HUDless_Buffer"); - _bufferState = InState; - - return true; -} - - -void FT_Dx12::SetBufferState(ID3D12GraphicsCommandList* InCommandList, D3D12_RESOURCE_STATES InState) -{ - if (_bufferState == InState) - return; - - D3D12_RESOURCE_BARRIER barrier = {}; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Transition.pResource = _buffer; - barrier.Transition.StateBefore = _bufferState; - barrier.Transition.StateAfter = InState; - barrier.Transition.Subresource = 0; - InCommandList->ResourceBarrier(1, &barrier); - _bufferState = InState; -} - -bool FT_Dx12::Dispatch(ID3D12Device* InDevice, ID3D12GraphicsCommandList* InCmdList, ID3D12Resource* InResource, ID3D12Resource* OutResource) -{ - if (!_init || InDevice == nullptr || InCmdList == nullptr || InResource == nullptr || OutResource == nullptr) - return false; - - LOG_DEBUG("[{0}] Start!", _name); - - _counter++; - _counter = _counter % 2; - - if (_cpuSrvHandle[_counter].ptr == NULL) - _cpuSrvHandle[_counter] = _srvHeap[_counter]->GetCPUDescriptorHandleForHeapStart(); - - if (_cpuUavHandle[_counter].ptr == NULL) - { - _cpuUavHandle[_counter] = _cpuSrvHandle[_counter]; - _cpuUavHandle[_counter].ptr += InDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - - if (_gpuSrvHandle[_counter].ptr == NULL) - _gpuSrvHandle[_counter] = _srvHeap[_counter]->GetGPUDescriptorHandleForHeapStart(); - - if (_gpuUavHandle[_counter].ptr == NULL) - { - _gpuUavHandle[_counter] = _gpuSrvHandle[_counter]; - _gpuUavHandle[_counter].ptr += InDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - - auto inDesc = InResource->GetDesc(); - auto outDesc = OutResource->GetDesc(); - - // Create SRV for Input Texture - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; - srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - srvDesc.Format = TranslateTypelessFormats(inDesc.Format); - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = 1; - srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Texture2D.ResourceMinLODClamp = 0.0f; - InDevice->CreateShaderResourceView(InResource, &srvDesc, _cpuSrvHandle[_counter]); - - // Create UAV for Output Texture - D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; - uavDesc.Format = DXGI_FORMAT_R32_UINT; - uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; - uavDesc.Texture2D.MipSlice = 0; - InDevice->CreateUnorderedAccessView(OutResource, nullptr, &uavDesc, _cpuUavHandle[_counter]); - - ID3D12DescriptorHeap* heaps[] = { _srvHeap[_counter] }; - InCmdList->SetDescriptorHeaps(_countof(heaps), heaps); - - InCmdList->SetComputeRootSignature(_rootSignature); - InCmdList->SetPipelineState(_pipelineState); - - InCmdList->SetComputeRootDescriptorTable(0, _gpuSrvHandle[_counter]); - InCmdList->SetComputeRootDescriptorTable(1, _gpuUavHandle[_counter]); - - UINT dispatchWidth = 0; - UINT dispatchHeight = 0; - - dispatchWidth = static_cast((Config::Instance()->CurrentFeature->DisplayWidth() + InNumThreadsX - 1) / InNumThreadsX); - dispatchHeight = (Config::Instance()->CurrentFeature->DisplayHeight() + InNumThreadsY - 1) / InNumThreadsY; - - InCmdList->Dispatch(dispatchWidth, dispatchHeight, 1); - - return true; -} - -FT_Dx12::FT_Dx12(std::string InName, ID3D12Device* InDevice, DXGI_FORMAT InFormat) : _name(InName), _device(InDevice), format(InFormat) -{ - if (InDevice == nullptr) - { - LOG_ERROR("InDevice is nullptr!"); - return; - } - - LOG_DEBUG("{0} start!", _name); - - // Describe and create the root signature - // --------------------------------------------------- - D3D12_DESCRIPTOR_RANGE descriptorRange[2]; - - // SRV Range (Input Texture) - descriptorRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - descriptorRange[0].NumDescriptors = 1; - descriptorRange[0].BaseShaderRegister = 0; // Assuming t0 register in HLSL for SRV - descriptorRange[0].RegisterSpace = 0; - descriptorRange[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - - // UAV Range (Output Texture) - descriptorRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - descriptorRange[1].NumDescriptors = 1; - descriptorRange[1].BaseShaderRegister = 0; // Assuming u0 register in HLSL for UAV - descriptorRange[1].RegisterSpace = 0; - descriptorRange[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - - // Define the root parameter (descriptor table) - // --------------------------------------------------- - D3D12_ROOT_PARAMETER rootParameters[2]; - - // Root Parameter for SRV - rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParameters[0].DescriptorTable.NumDescriptorRanges = 1; // One range (SRV) - rootParameters[0].DescriptorTable.pDescriptorRanges = &descriptorRange[0]; // Point to the SRV range - rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - - // Root Parameter for UAV - rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParameters[1].DescriptorTable.NumDescriptorRanges = 1; // One range (UAV) - rootParameters[1].DescriptorTable.pDescriptorRanges = &descriptorRange[1]; // Point to the UAV range - rootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - - - // A root signature is an array of root parameters - // --------------------------------------------------- - D3D12_ROOT_SIGNATURE_DESC rootSigDesc; - rootSigDesc.NumParameters = 2; // Two root parameters - rootSigDesc.pParameters = rootParameters; - rootSigDesc.NumStaticSamplers = 0; - rootSigDesc.pStaticSamplers = nullptr; - rootSigDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; - - ID3DBlob* errorBlob; - ID3DBlob* signatureBlob; - - do - { - auto hr = D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signatureBlob, &errorBlob); - - if (FAILED(hr)) - { - LOG_ERROR("[{0}] D3D12SerializeRootSignature error {1:x}", _name, hr); - break; - } - - hr = InDevice->CreateRootSignature(0, signatureBlob->GetBufferPointer(), signatureBlob->GetBufferSize(), IID_PPV_ARGS(&_rootSignature)); - - if (FAILED(hr)) - { - LOG_ERROR("[{0}] CreateRootSignature error {1:x}", _name, hr); - break; - } - - } while (false); - - if (errorBlob != nullptr) - { - errorBlob->Release(); - errorBlob = nullptr; - } - - if (signatureBlob != nullptr) - { - signatureBlob->Release(); - signatureBlob = nullptr; - } - - if (_rootSignature == nullptr) - { - LOG_ERROR("[{0}] _rootSignature is null!", _name); - return; - } - - // Compile shader blobs - ID3DBlob* _recEncodeShader = nullptr; - - if (InFormat == DXGI_FORMAT_R10G10B10A2_UNORM) - { - _recEncodeShader = FT_CompileShader(ftR10G10B10A2Code.c_str(), "CSMain", "cs_5_0"); - } - else if (InFormat == DXGI_FORMAT_R8G8B8A8_UNORM) - { - _recEncodeShader = FT_CompileShader(ftR8G8B8A8Code.c_str(), "CSMain", "cs_5_0"); - } - else if (InFormat == DXGI_FORMAT_B8G8R8A8_UNORM) - { - _recEncodeShader = FT_CompileShader(ftB8G8R8A8Code.c_str(), "CSMain", "cs_5_0"); - } - else - { - LOG_ERROR("[{0}] texture format is not found!", _name); - return; - } - - if (_recEncodeShader == nullptr) - { - LOG_ERROR("[{0}] CompileShader error!", _name); - return; - } - - // create pso objects - if (!CreateComputeShader(InDevice, _rootSignature, &_pipelineState, _recEncodeShader)) - { - LOG_ERROR("[{0}] CreateComputeShader error!", _name); - return; - } - - if (_recEncodeShader != nullptr) - { - _recEncodeShader->Release(); - _recEncodeShader = nullptr; - } - - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.NumDescriptors = 2; // SRV + UAV - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - - auto hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[0])); - - if (FAILED(hr)) - { - LOG_ERROR("[{0}] CreateDescriptorHeap[0] error {1:x}", _name, hr); - return; - } - - hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[1])); - - if (FAILED(hr)) - { - LOG_ERROR("[{0}] CreateDescriptorHeap[1] error {1:x}", _name, hr); - return; - } - - hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[2])); - - if (FAILED(hr)) - { - LOG_ERROR("[{0}] CreateDescriptorHeap[2] error {1:x}", _name, hr); - return; - } - - _init = _srvHeap[2] != nullptr; -} - -FT_Dx12::~FT_Dx12() -{ - if (!_init) - return; - - ID3D12Fence* d3d12Fence = nullptr; - - do - { - if (_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&d3d12Fence)) != S_OK) - break; - - d3d12Fence->Signal(999); - - HANDLE fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); - - if (fenceEvent != NULL && d3d12Fence->SetEventOnCompletion(999, fenceEvent) == S_OK) - { - WaitForSingleObject(fenceEvent, INFINITE); - CloseHandle(fenceEvent); - } - - } while (false); - - if (d3d12Fence != nullptr) - { - d3d12Fence->Release(); - d3d12Fence = nullptr; - } - - if (_pipelineState != nullptr) - { - _pipelineState->Release(); - _pipelineState = nullptr; - } - - if (_rootSignature != nullptr) - { - _rootSignature->Release(); - _rootSignature = nullptr; - } - - if (_srvHeap[0] != nullptr) - { - _srvHeap[0]->Release(); - _srvHeap[0] = nullptr; - } - - if (_srvHeap[1] != nullptr) - { - _srvHeap[1]->Release(); - _srvHeap[1] = nullptr; - } - - if (_srvHeap[2] != nullptr) - { - _srvHeap[2]->Release(); - _srvHeap[2] = nullptr; - } - - if (_buffer != nullptr) - { - _buffer->Release(); - _buffer = nullptr; - } -} diff --git a/OptiScaler/format_transfer/FT_Dx12.h b/OptiScaler/format_transfer/FT_Dx12.h deleted file mode 100644 index 8d7bbe47..00000000 --- a/OptiScaler/format_transfer/FT_Dx12.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "../pch.h" - -#include "FT_Common.h" - -#include -#include "../d3dx/d3dx12.h" - -class FT_Dx12 -{ -private: - std::string _name = ""; - bool _init = false; - ID3D12RootSignature* _rootSignature = nullptr; - ID3D12PipelineState* _pipelineState = nullptr; - ID3D12DescriptorHeap* _srvHeap[3] = { nullptr, nullptr, nullptr }; - D3D12_CPU_DESCRIPTOR_HANDLE _cpuSrvHandle[2]{ { NULL }, { NULL } }; - D3D12_CPU_DESCRIPTOR_HANDLE _cpuUavHandle[2]{ { NULL }, { NULL } }; - D3D12_GPU_DESCRIPTOR_HANDLE _gpuSrvHandle[2]{ { NULL }, { NULL } }; - D3D12_GPU_DESCRIPTOR_HANDLE _gpuUavHandle[2]{ { NULL }, { NULL } }; - int _counter = 0; - - uint32_t InNumThreadsX = 512; - uint32_t InNumThreadsY = 1; - - ID3D12Device* _device = nullptr; - ID3D12Resource* _buffer = nullptr; - D3D12_RESOURCE_STATES _bufferState = D3D12_RESOURCE_STATE_COMMON; - DXGI_FORMAT format; - -public: - bool CreateBufferResource(ID3D12Device* InDevice, ID3D12Resource* InSource, D3D12_RESOURCE_STATES InState); - void SetBufferState(ID3D12GraphicsCommandList* InCommandList, D3D12_RESOURCE_STATES InState); - bool Dispatch(ID3D12Device* InDevice, ID3D12GraphicsCommandList* InCmdList, ID3D12Resource* InResource, ID3D12Resource* OutResource); - - ID3D12Resource* Buffer() { return _buffer; } - bool IsInit() const { return _init; } - bool CanRender() const { return _init && _buffer != nullptr; } - DXGI_FORMAT Format() const { return format; } - - FT_Dx12(std::string InName, ID3D12Device* InDevice, DXGI_FORMAT InFormat); - - ~FT_Dx12(); -}; \ No newline at end of file diff --git a/OptiScaler/imgui/imgui_common.cpp b/OptiScaler/imgui/imgui_common.cpp index 51c05806..e02fc4da 100644 --- a/OptiScaler/imgui/imgui_common.cpp +++ b/OptiScaler/imgui/imgui_common.cpp @@ -911,7 +911,7 @@ void ImGuiCommon::RenderMenu() } } - ShowHelpMarker("Enable HUD stability fix (Might cause crashes!)"); + ShowHelpMarker("Enable HUD stability fix, might cause crashes!"); ImGui::BeginDisabled(!Config::Instance()->FGHUDFix.value_or(false)); @@ -929,38 +929,16 @@ void ImGuiCommon::RenderMenu() Config::Instance()->FGHUDLimit = hudFixLimit; } - - ImGui::SameLine(0.0f, 16.0f); - - auto hudDeep = Config::Instance()->FGHUDPrevious.value_or(false); - if (ImGui::Checkbox("Deep", &hudDeep)) - Config::Instance()->FGHUDPrevious = hudDeep; - - ImGui::PopItemWidth(); ShowHelpMarker("Delay HUDless capture, high values might cause crash!"); - - //ImGui::PushItemWidth(85.0); - //bool fgSkipInstance = Config::Instance()->FGSkipInstanced.value_or(true); - //if (ImGui::Checkbox("Skip Instanced", &fgSkipInstance)) - //{ - // if (fgSkipInstance) - // Config::Instance()->FGSkipIndexedInstanced = false; - - // Config::Instance()->FGSkipInstanced = fgSkipInstance; - //} - + //ImGui::SameLine(0.0f, 16.0f); - //bool fgSkipIndexed = Config::Instance()->FGSkipIndexedInstanced.value_or(false); - //if (ImGui::Checkbox("Skip Indexed", &fgSkipIndexed)) - //{ - // if (fgSkipIndexed) - // Config::Instance()->FGSkipInstanced = false; + //auto hudExtended = Config::Instance()->FGHUDPrevious.value_or(false); + //if (ImGui::Checkbox("Extended", &hudExtended)) + // Config::Instance()->FGHUDPrevious = hudExtended; + //ShowHelpMarker("Extended HUDless checks, might cause crash and slowdowns!"); - // Config::Instance()->FGSkipIndexedInstanced = fgSkipIndexed; - //} - - //ImGui::PopItemWidth(); + ImGui::PopItemWidth(); ImGui::EndDisabled(); @@ -976,7 +954,7 @@ void ImGuiCommon::RenderMenu() LOG_DEBUG_ONLY("Async set FGChanged"); } } - ShowHelpMarker("Enable Async for better FG performance (Might cause crashes, especially with HUD Fix!)"); + ShowHelpMarker("Enable Async for better FG performance\nMight cause crashes, especially with HUD Fix!"); bool fgDV = Config::Instance()->FGDebugView.value_or(false); if (ImGui::Checkbox("FG Debug View", &fgDV)) diff --git a/OptiScaler/imgui/imgui_dx12.cpp b/OptiScaler/imgui/imgui_dx12.cpp index 68c9533b..c46cbc86 100644 --- a/OptiScaler/imgui/imgui_dx12.cpp +++ b/OptiScaler/imgui/imgui_dx12.cpp @@ -163,9 +163,13 @@ Imgui_Dx12::Imgui_Dx12(HWND handle, ID3D12Device* pDevice) : ImguiDxBase(handle) srvDesc.NumDescriptors = 1; srvDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + Config::Instance()->SkipHeapCapture = true; + if (pDevice->CreateDescriptorHeap(&srvDesc, IID_PPV_ARGS(&_srvDescHeap)) != S_OK) return; + Config::Instance()->SkipHeapCapture = false; + Dx12Ready(); _srvDescHeap->SetName(L"Imgui_Dx12_srvDescHeap"); diff --git a/OptiScaler/imgui/imgui_overlay_dx.cpp b/OptiScaler/imgui/imgui_overlay_dx.cpp index baf7ea31..0946a836 100644 --- a/OptiScaler/imgui/imgui_overlay_dx.cpp +++ b/OptiScaler/imgui/imgui_overlay_dx.cpp @@ -16,10 +16,11 @@ #include #include "../depth_upscale/DU_Dx12.h" +#include // FG stuff -struct BackbufferInfo +typedef struct BackbufferInfo { // RTV handle for backbuffer SIZE_T cpuHandle = NULL; @@ -34,12 +35,13 @@ struct BackbufferInfo ID3D12Resource* hudless = nullptr; } backbuffer_info; -struct HeapInfo +typedef struct HeapInfo { SIZE_T cpuStart = NULL; SIZE_T cpuEnd = NULL; SIZE_T gpuStart = NULL; SIZE_T gpuEnd = NULL; + UINT numDescriptors = 0; } heap_info; // Hooks for FG @@ -53,6 +55,10 @@ typedef void (*PFN_CopyTextureRegion)(ID3D12GraphicsCommandList* This, D3D12_TEX typedef HRESULT(*PFN_CreateDescriptorHeap)(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_DESC* pDescriptorHeapDesc, REFIID riid, void** ppvHeap); typedef void(*PFN_CreateShaderResourceView)(ID3D12Device* This, ID3D12Resource* pResource, D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); typedef void(*PFN_SetGraphicsRootDescriptorTable)(ID3D12GraphicsCommandList* This, UINT RootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); +typedef void(*PFN_CopyDescriptors)(UINT NumDestDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, UINT* pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges, + D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, UINT* pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); +typedef void(*PFN_CopyDescriptorsSimple)(UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + static PFN_CreateRenderTargetView o_CreateRenderTargetView = nullptr; static PFN_OMSetRenderTargets o_OMSetRenderTargets = nullptr; @@ -63,6 +69,8 @@ static PFN_CopyTextureRegion o_CopyTextureRegion = nullptr; static PFN_CreateDescriptorHeap o_CreateDescriptorHeap = nullptr; static PFN_CreateShaderResourceView o_CreateShaderResourceView = nullptr; static PFN_SetGraphicsRootDescriptorTable o_SetGraphicsRootDescriptorTable = nullptr; +static PFN_CopyDescriptors o_CopyDescriptors = nullptr; +static PFN_CopyDescriptorsSimple o_CopyDescriptorsSimple = nullptr; // FSR 3.x methods static PfnFfxCreateContext _createContext = nullptr; @@ -84,19 +92,16 @@ static ankerl::unordered_dense::map fgBuffers; /// /// Captured heap infos /// -static ankerl::unordered_dense::map fgHeaps; +static std::list fgHeaps; /// /// Captured resources by gpu addresses /// static ankerl::unordered_dense::map fgHandleAddressResources; +static ankerl::unordered_dense::map fgHandleAddressResourcesByGpuHandle; -/// -/// Descriptor handle increment size for SRV_UAV_CBV -/// -static UINT descriptorHandleIncrementSize = 0; - -static std::mutex heapMutex; +static std::shared_mutex heapMutex; +static std::shared_mutex resourceMutex; /// /// Captured cpu handles @@ -521,9 +526,9 @@ static void hkCreateRenderTargetView(ID3D12Device* This, ID3D12Resource* pResour o_CreateRenderTargetView(This, pResource, pDesc, DestDescriptor); // Swapchain changed - if (Config::Instance()->SGChanged) + if (Config::Instance()->SCChanged) { - LOG_DEBUG_ONLY(" FG SGChanged: true"); + LOG_DEBUG_ONLY(" FG SCChanged: true"); fgCaptureRTVs = true; fgTargetFrame = frameCounter + 60; @@ -534,33 +539,41 @@ static void hkCreateRenderTargetView(ID3D12Device* This, ID3D12Resource* pResour } fgBuffers.clear(); - //fgHeaps.clear(); - //fgHandleAddressResources.clear(); fgCapturedBufferCount = 0; - Config::Instance()->SGChanged = false; + Config::Instance()->SCChanged = false; } if (pResource == nullptr) return; - // Try to match resource with cpu & gpu handle info - for (auto& [key, val] : fgHeaps) { - if (val.cpuStart <= DestDescriptor.ptr && val.cpuEnd >= DestDescriptor.ptr) + std::shared_lock lock(heapMutex); + + // Try to match resource with cpu & gpu handle info + for (auto& val : fgHeaps) { - auto addr = DestDescriptor.ptr - val.cpuStart; - auto index = addr / descriptorHandleIncrementSize; - auto gpuAddr = val.gpuStart + (index * descriptorHandleIncrementSize); + if (val.cpuStart <= DestDescriptor.ptr && val.cpuEnd >= DestDescriptor.ptr) + { + auto increment = This->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + auto addr = DestDescriptor.ptr - val.cpuStart; + auto index = addr / increment; + auto gpuAddr = val.gpuStart + (index * increment); - heapMutex.lock(); - HeapInfo info{}; - info.cpuStart = DestDescriptor.ptr; - info.gpuStart = gpuAddr; - fgHandleAddressResources.insert_or_assign(pResource, info); - heapMutex.unlock(); + HeapInfo info{}; + info.cpuStart = DestDescriptor.ptr; + info.gpuStart = gpuAddr; - break; + std::unique_lock lock2(resourceMutex); + fgHandleAddressResources.insert_or_assign(pResource, info); + + if (val.gpuStart != 0) + fgHandleAddressResourcesByGpuHandle.insert_or_assign(gpuAddr, pResource); + else + LOG_DEBUG_ONLY("Gpu start is 0, CPU ptr : {}", (UINT64)DestDescriptor.ptr); + + break; + } } } @@ -654,6 +667,8 @@ static void hkOMSetRenderTargets(ID3D12GraphicsCommandList* This, UINT NumRender { hudless = bufferInfo->hudless; + std::shared_lock lock2(resourceMutex); + if (bufferInfo->prevCpuHandle == NULL && fgHandleAddressResources.contains(bufferInfo->prev)) bufferInfo->prevCpuHandle = fgHandleAddressResources[bufferInfo->prev].cpuStart; } @@ -662,6 +677,8 @@ static void hkOMSetRenderTargets(ID3D12GraphicsCommandList* This, UINT NumRender { bufferInfo->hudless = hudless; + std::shared_lock lock2(resourceMutex); + if (fgHandleAddressResources.contains(bufferInfo->prev)) bufferInfo->prevCpuHandle = fgHandleAddressResources[bufferInfo->prev].cpuStart; } @@ -868,8 +885,12 @@ static void hkCopyTextureRegion(ID3D12GraphicsCommandList* This, D3D12_TEXTURE_C auto bufferInfo = &fgBuffers[pDst->pResource]; bufferInfo->prev = pSrc->pResource; - if (fgHandleAddressResources.contains(bufferInfo->prev)) - bufferInfo->prevCpuHandle = fgHandleAddressResources[bufferInfo->prev].cpuStart; + { + std::shared_lock lock2(resourceMutex); + + if (fgHandleAddressResources.contains(bufferInfo->prev)) + bufferInfo->prevCpuHandle = fgHandleAddressResources[bufferInfo->prev].cpuStart; + } // capture hudless if (bufferInfo->hudless != nullptr) @@ -920,6 +941,8 @@ static void hkDrawInstanced(ID3D12GraphicsCommandList* This, UINT VertexCountPer { auto bufferInfo = &fgBuffers[fgCurrentSCBuffer]; bufferInfo->prev = fgPreviousBuffer; + + std::shared_lock lock2(resourceMutex); bufferInfo->prevCpuHandle = fgHandleAddressResources[fgPreviousBuffer].cpuStart; } @@ -956,6 +979,8 @@ static void hkDrawIndexedInstanced(ID3D12GraphicsCommandList* This, UINT IndexCo { auto bufferInfo = &fgBuffers[fgCurrentSCBuffer]; bufferInfo->prev = fgPreviousBuffer; + + std::shared_lock lock2(resourceMutex); bufferInfo->prevCpuHandle = fgHandleAddressResources[fgPreviousBuffer].cpuStart; } @@ -977,17 +1002,17 @@ static void hkSetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList* This, UI if (!Config::Instance()->FGHUDPrevious.value_or(false)) return; - // assume first one is source - if (RootParameterIndex == 0) { - for (auto& [key, val] : fgHandleAddressResources) + std::shared_lock lock(resourceMutex); + + // assume first one is source + if (RootParameterIndex == 0 && fgHandleAddressResourcesByGpuHandle.contains(BaseDescriptor.ptr)) { - // try to match resource with gpu handle - if (BaseDescriptor.ptr == val.gpuStart) - { - fgPreviousBuffer = key; - return; - } + fgPreviousBuffer = fgHandleAddressResourcesByGpuHandle[BaseDescriptor.ptr]; + } + else + { + LOG_DEBUG_ONLY("Miss: {0:X}", (UINT64)BaseDescriptor.ptr); } } } @@ -996,39 +1021,35 @@ static HRESULT hkCreateDescriptorHeap(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_ { auto result = o_CreateDescriptorHeap(This, pDescriptorHeapDesc, riid, ppvHeap); - // Swapchain changed - if (Config::Instance()->SGChanged) - { - LOG_DEBUG_ONLY(" FG SGChanged: true"); - fgCaptureRTVs = true; - fgTargetFrame = frameCounter + 60; - - for (auto const& [key, val] : fgBuffers) - { - if (val.hudless != nullptr) - val.hudless->Release(); - } - - fgBuffers.clear(); - //fgHeaps.clear(); - //fgHandleAddressResources.clear(); - - fgCapturedBufferCount = 0; - Config::Instance()->SGChanged = false; - } - - // try to calculate handle infos for heap - if (result == S_OK && pDescriptorHeapDesc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && pDescriptorHeapDesc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) + // try to calculate handle ranges for heap + if (result == S_OK && !Config::Instance()->SkipHeapCapture && (pDescriptorHeapDesc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || pDescriptorHeapDesc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_RTV)) //&& pDescriptorHeapDesc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) { HeapInfo info{}; auto heap = (ID3D12DescriptorHeap*)(*ppvHeap); - - info.cpuStart = (SIZE_T)(heap->GetCPUDescriptorHandleForHeapStart().ptr); + auto increment = This->GetDescriptorHandleIncrementSize(pDescriptorHeapDesc->Type); + info.numDescriptors = pDescriptorHeapDesc->NumDescriptors; info.gpuStart = (SIZE_T)(heap->GetGPUDescriptorHandleForHeapStart().ptr); - info.cpuEnd = info.cpuStart + (descriptorHandleIncrementSize * pDescriptorHeapDesc->NumDescriptors); // most probably will broke some stuff - info.gpuEnd = info.gpuStart + (descriptorHandleIncrementSize * pDescriptorHeapDesc->NumDescriptors); // most probably will broke some stuff + info.cpuStart = (SIZE_T)(heap->GetCPUDescriptorHandleForHeapStart().ptr); + info.cpuEnd = info.cpuStart + (increment * info.numDescriptors); + info.gpuEnd = info.gpuStart + (increment * info.numDescriptors); - fgHeaps.insert_or_assign(heap, info); + //if (info.gpuStart != 0) + //{ + LOG_DEBUG_ONLY("Found heap, type: {}, cpu: {}-{}, gpu: {}-{}, desc count: {}", (UINT)pDescriptorHeapDesc->Type, info.cpuStart, info.cpuEnd, info.gpuStart, info.gpuEnd, info.numDescriptors); + + std::unique_lock lock(heapMutex); + fgHeaps.push_back(info); + //} + //else + //{ + // auto heap = (ID3D12DescriptorHeap*)(*ppvHeap); + // LOG_DEBUG_ONLY("Skipping, no GPU handle, type: {}, cpu: {}-{}", (UINT)pDescriptorHeapDesc->Type, info.cpuStart, info.cpuEnd); + //} + } + else + { + auto heap = (ID3D12DescriptorHeap*)(*ppvHeap); + LOG_DEBUG_ONLY("Skipping, type: {}, cpuStart: {}, gpu start: {}", (UINT)pDescriptorHeapDesc->Type, (SIZE_T)(heap->GetCPUDescriptorHandleForHeapStart().ptr), (SIZE_T)(heap->GetGPUDescriptorHandleForHeapStart().ptr)); } return result; @@ -1038,52 +1059,64 @@ static void hkCreateShaderResourceView(ID3D12Device* This, ID3D12Resource* pReso { o_CreateShaderResourceView(This, pResource, pDesc, DestDescriptor); - if (pResource == nullptr || pDesc == nullptr || pDesc->ViewDimension != D3D12_SRV_DIMENSION_TEXTURE2D) + if (pResource == nullptr || pDesc == nullptr || pDesc->ViewDimension != D3D12_SRV_DIMENSION_TEXTURE2D) // || pDesc->Shader4ComponentMapping != D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING) return; - if (Config::Instance()->SGChanged) { - LOG_DEBUG_ONLY(" FG SGChanged: true"); - fgCaptureRTVs = true; - fgTargetFrame = frameCounter + 60; + std::shared_lock lock(heapMutex); - for (auto const& [key, val] : fgBuffers) + // try to find heap of resource + for (auto& val : fgHeaps) { - if (val.hudless != nullptr) - val.hudless->Release(); - } + if (val.cpuStart <= DestDescriptor.ptr && val.cpuEnd >= DestDescriptor.ptr) + { + auto incSize = This->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + auto addr = DestDescriptor.ptr - val.cpuStart; + auto index = addr / incSize; + auto gpuAddr = val.gpuStart + (index * incSize); - fgBuffers.clear(); - //fgHeaps.clear(); - //fgHandleAddressResources.clear(); + HeapInfo info{}; + info.cpuStart = DestDescriptor.ptr; + info.gpuStart = gpuAddr; - fgCapturedBufferCount = 0; - Config::Instance()->SGChanged = false; - } + std::unique_lock lock(resourceMutex); + fgHandleAddressResources.insert_or_assign(pResource, info); - // try to find heap of resource - for (auto& [key, val] : fgHeaps) - { - if (val.cpuStart <= DestDescriptor.ptr && val.cpuEnd >= DestDescriptor.ptr) - { - auto addr = DestDescriptor.ptr - val.cpuStart; - auto index = addr / descriptorHandleIncrementSize; - auto gpuAddr = val.gpuStart + (index * descriptorHandleIncrementSize); + if (val.gpuStart != 0) + fgHandleAddressResourcesByGpuHandle.insert_or_assign(gpuAddr, pResource); + else + LOG_DEBUG_ONLY("Gpu start is 0, CPU ptr : {}", (UINT64)DestDescriptor.ptr); - heapMutex.lock(); - HeapInfo info{}; - info.cpuStart = DestDescriptor.ptr; - info.gpuStart = gpuAddr; - fgHandleAddressResources.insert_or_assign(pResource, info); - heapMutex.unlock(); - - return; + return; + } } } - LOG_DEBUG_ONLY("Not found"); + LOG_DEBUG_ONLY("Not found, CPU ptr: {}", (UINT64)DestDescriptor.ptr); } +static void __stdcall hkCopyDescriptors(UINT NumDestDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, UINT* pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges, + D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, UINT* pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) +{ + o_CopyDescriptors(NumDestDescriptorRanges, pDestDescriptorRangeStarts, pDestDescriptorRangeSizes, NumSrcDescriptorRanges, pSrcDescriptorRangeStarts, pSrcDescriptorRangeSizes, DescriptorHeapsType); + + if (DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_RTV) + { + LOG_DEBUG_ONLY("Found"); + } +} + +static void __stdcall hkCopyDescriptorsSimple(UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) +{ + o_CopyDescriptorsSimple(NumDescriptors, DestDescriptorRangeStart, SrcDescriptorRangeStart, DescriptorHeapsType); + + if (DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_RTV) + { + LOG_DEBUG_ONLY("Found"); + } +} + + static int GetCorrectDXGIFormat(int eCurrentFormat) { switch (eCurrentFormat) @@ -1664,7 +1697,9 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI Config::Instance()->dxgiSkipSpoofing = true; fgSkipSCWrapping = true; + Config::Instance()->SkipHeapCapture = true; auto result = _createContext(&ImGuiOverlayDx::fgSwapChainContext, &createSwapChainDesc.header, nullptr); + Config::Instance()->SkipHeapCapture = false; fgSkipSCWrapping = false; Config::Instance()->dxgiSkipSpoofing = false; @@ -1762,7 +1797,9 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H Config::Instance()->dxgiSkipSpoofing = true; fgSkipSCWrapping = true; + Config::Instance()->SkipHeapCapture = true; auto result = _createContext(&ImGuiOverlayDx::fgSwapChainContext, &createSwapChainDesc.header, nullptr); + Config::Instance()->SkipHeapCapture = false; fgSkipSCWrapping = false; Config::Instance()->dxgiSkipSpoofing = false; @@ -2030,8 +2067,8 @@ static void HookCommandList(ID3D12Device* InDevice) if (o_CopyResource != nullptr) DetourAttach(&(PVOID&)o_CopyResource, hkCopyResource); - if (o_SetGraphicsRootDescriptorTable != nullptr) - DetourAttach(&(PVOID&)o_SetGraphicsRootDescriptorTable, hkSetGraphicsRootDescriptorTable); + //if (o_SetGraphicsRootDescriptorTable != nullptr) + // DetourAttach(&(PVOID&)o_SetGraphicsRootDescriptorTable, hkSetGraphicsRootDescriptorTable); DetourTransactionCommit(); } @@ -2057,6 +2094,8 @@ static void HookToDevice(ID3D12Device* InDevice) o_CreateDescriptorHeap = (PFN_CreateDescriptorHeap)pVTable[14]; o_CreateSampler = (PFN_CreateSampler)pVTable[22]; + o_CopyDescriptors = (PFN_CopyDescriptors)pVTable[23]; + o_CopyDescriptorsSimple = (PFN_CopyDescriptorsSimple)pVTable[24]; o_CreateShaderResourceView = (PFN_CreateShaderResourceView)pVTable[18]; o_CreateRenderTargetView = (PFN_CreateRenderTargetView)pVTable[20]; @@ -2075,15 +2114,19 @@ static void HookToDevice(ID3D12Device* InDevice) if (o_CreateRenderTargetView != nullptr) DetourAttach(&(PVOID&)o_CreateRenderTargetView, hkCreateRenderTargetView); - if (o_CreateShaderResourceView != nullptr) - DetourAttach(&(PVOID&)o_CreateShaderResourceView, hkCreateShaderResourceView); + //if (o_CreateShaderResourceView != nullptr) + // DetourAttach(&(PVOID&)o_CreateShaderResourceView, hkCreateShaderResourceView); + + //if (o_CopyDescriptors != nullptr) + // DetourAttach(&(PVOID&)o_CopyDescriptors, hkCopyDescriptors); + + //if (o_CopyDescriptorsSimple != nullptr) + // DetourAttach(&(PVOID&)o_CopyDescriptorsSimple, hkCopyDescriptorsSimple); DetourTransactionCommit(); } HookCommandList(InDevice); - - descriptorHandleIncrementSize = InDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } static void HookToDevice(ID3D11Device* InDevice) @@ -2470,6 +2513,8 @@ static void RenderImGui_DX12(IDXGISwapChain* pSwapChainPlain) desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; desc.NodeMask = 1; + Config::Instance()->SkipHeapCapture = true; + result = device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dRtvDescHeap)); if (result != S_OK) { @@ -2497,6 +2542,8 @@ static void RenderImGui_DX12(IDXGISwapChain* pSwapChainPlain) desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; result = device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dSrvDescHeap)); + + Config::Instance()->SkipHeapCapture = false; if (result != S_OK) { LOG_ERROR("CreateDescriptorHeap(g_pd3dSrvDescHeap): {0:X}", (unsigned long)result); diff --git a/OptiScaler/imgui/wrapped_swapchain.cpp b/OptiScaler/imgui/wrapped_swapchain.cpp index fb733e00..577c79f2 100644 --- a/OptiScaler/imgui/wrapped_swapchain.cpp +++ b/OptiScaler/imgui/wrapped_swapchain.cpp @@ -124,7 +124,7 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount, UINT Width, UINT if (Config::Instance()->CurrentFeature != nullptr) Config::Instance()->FGChanged = true; - Config::Instance()->SGChanged = true; + Config::Instance()->SCChanged = true; std::this_thread::sleep_for(std::chrono::milliseconds(150)); @@ -159,7 +159,7 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers1(UINT BufferCount, UINT Width, UIN if (Config::Instance()->CurrentFeature != nullptr) Config::Instance()->FGChanged = true; - Config::Instance()->SGChanged = true; + Config::Instance()->SCChanged = true; std::this_thread::sleep_for(std::chrono::milliseconds(150)); @@ -186,7 +186,7 @@ HRESULT WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullscreen, IDXGIOutput* if (Config::Instance()->CurrentFeature != nullptr) Config::Instance()->FGChanged = true; - Config::Instance()->SGChanged = true; + Config::Instance()->SCChanged = true; std::this_thread::sleep_for(std::chrono::milliseconds(150)); diff --git a/OptiScaler/output_scaling/OS_Dx12.cpp b/OptiScaler/output_scaling/OS_Dx12.cpp index 174cd3e1..bb28180a 100644 --- a/OptiScaler/output_scaling/OS_Dx12.cpp +++ b/OptiScaler/output_scaling/OS_Dx12.cpp @@ -443,6 +443,8 @@ OS_Dx12::OS_Dx12(std::string InName, ID3D12Device* InDevice, bool InUpsample) : heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + Config::Instance()->SkipHeapCapture = true; + auto hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[0])); if (FAILED(hr)) @@ -461,6 +463,8 @@ OS_Dx12::OS_Dx12(std::string InName, ID3D12Device* InDevice, bool InUpsample) : hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[2])); + Config::Instance()->SkipHeapCapture = false; + if (FAILED(hr)) { LOG_ERROR("[{0}] CreateDescriptorHeap[2] error {1:x}", _name, hr); diff --git a/OptiScaler/rcas/RCAS_Dx12.cpp b/OptiScaler/rcas/RCAS_Dx12.cpp index ed543360..9cb7f6e6 100644 --- a/OptiScaler/rcas/RCAS_Dx12.cpp +++ b/OptiScaler/rcas/RCAS_Dx12.cpp @@ -438,6 +438,8 @@ RCAS_Dx12::RCAS_Dx12(std::string InName, ID3D12Device* InDevice) : _name(InName) heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + Config::Instance()->SkipHeapCapture = true; + auto hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[0])); if (FAILED(hr)) @@ -464,6 +466,8 @@ RCAS_Dx12::RCAS_Dx12(std::string InName, ID3D12Device* InDevice) : _name(InName) hr = InDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_srvHeap[3])); + Config::Instance()->SkipHeapCapture = false; + if (FAILED(hr)) { LOG_ERROR("[{0}] CreateDescriptorHeap[3] error {1:x}", _name, (unsigned int)hr);