diff --git a/OptiScaler/NVNGX_DLSS_Dx12.cpp b/OptiScaler/NVNGX_DLSS_Dx12.cpp index c1c03c7b..d99acdb8 100644 --- a/OptiScaler/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/NVNGX_DLSS_Dx12.cpp @@ -1412,7 +1412,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom if (Config::Instance()->CurrentFeature != nullptr) fgLastFGFrame = Config::Instance()->CurrentFeature->FrameCount(); - + auto dispatchResult = FfxApiProxy::D3D12_Dispatch()(reinterpret_cast(pUserCtx), ¶ms->header); LOG_DEBUG("(FG) D3D12_Dispatch result: {}", (UINT)dispatchResult); @@ -1535,9 +1535,11 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom dfgPrepare.viewSpaceToMetersFactor = 1.0; dfgPrepare.frameTimeDelta = msDelta; + FrameGen_Dx12::ffxMutex.lock(); Config::Instance()->dxgiSkipSpoofing = true; retCode = FfxApiProxy::D3D12_Dispatch()(&FrameGen_Dx12::fgContext, &dfgPrepare.header); Config::Instance()->dxgiSkipSpoofing = false; + FrameGen_Dx12::ffxMutex.unlock(); if (retCode != FFX_API_RETURN_OK) LOG_ERROR("(FG) D3D12_Dispatch result: {}({})", retCode, FfxApiProxy::ReturnCodeToString(retCode)); diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp index 21e2c57f..1b5d23cf 100644 --- a/OptiScaler/hooks/HooksDx.cpp +++ b/OptiScaler/hooks/HooksDx.cpp @@ -122,7 +122,8 @@ typedef void(*PFN_CreateUnorderedAccessView)(ID3D12Device* This, ID3D12Resource* typedef HRESULT(*PFN_CreateDescriptorHeap)(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_DESC* pDescriptorHeapDesc, REFIID riid, void** ppvHeap); typedef void(*PFN_CopyDescriptors)(ID3D12Device* This, 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)(ID3D12Device* This, UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); -typedef UINT(*PFN_slInit)(const void* pref, uint64_t sdkVersion); + +typedef HRESULT(*PFN_Present)(void* This, UINT SyncInterval, UINT Flags); // Command list hooks for FG typedef void(*PFN_OMSetRenderTargets)(ID3D12GraphicsCommandList* This, UINT NumRenderTargetDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE* pRenderTargetDescriptors, BOOL RTsSingleHandleToDescriptorRange, D3D12_CPU_DESCRIPTOR_HANDLE* pDepthStencilDescriptor); @@ -146,6 +147,7 @@ static PFN_CreateUnorderedAccessView o_CreateUnorderedAccessView = nullptr; static PFN_CreateDescriptorHeap o_CreateDescriptorHeap = nullptr; static PFN_CopyDescriptors o_CopyDescriptors = nullptr; static PFN_CopyDescriptorsSimple o_CopyDescriptorsSimple = nullptr; +static PFN_Present o_FGSCPresent = nullptr; // Original method calls for command list static PFN_OMSetRenderTargets o_OMSetRenderTargets = nullptr; @@ -182,7 +184,6 @@ static ShaderType fgSourceType = None; // mutexes static std::shared_mutex heapMutex; static std::shared_mutex resourceMutex; -static std::shared_mutex ffxMutex; static std::shared_mutex hudlessMutex[FrameGen_Dx12::FG_BUFFER_SIZE]; static std::shared_mutex counterMutex[FrameGen_Dx12::FG_BUFFER_SIZE]; @@ -233,7 +234,6 @@ static PFN_CreateDXGIFactory2 o_CreateDXGIFactory2 = nullptr; static PFN_CreateDXGIFactory o_SL_CreateDXGIFactory = nullptr; static PFN_CreateDXGIFactory1 o_SL_CreateDXGIFactory1 = nullptr; static PFN_CreateDXGIFactory2 o_SL_CreateDXGIFactory2 = nullptr; -static PFN_slInit o_SL_slInit = nullptr; inline static PFN_EnumAdapters2 ptrEnumAdapters = nullptr; inline static PFN_EnumAdapters12 ptrEnumAdapters1 = nullptr; @@ -519,8 +519,6 @@ static void GetHudless(ID3D12GraphicsCommandList* This) if (Config::Instance()->CurrentFeature != nullptr) fgLastFGFrame = Config::Instance()->CurrentFeature->FrameCount(); - std::unique_lock lock(ffxMutex); - dispatchResult = FfxApiProxy::D3D12_Dispatch()(reinterpret_cast(pUserCtx), ¶ms->header); ID3D12CommandList* cl[1] = { nullptr }; result = FrameGen_Dx12::fgCopyCommandList->Close(); @@ -599,10 +597,14 @@ static void GetHudless(ID3D12GraphicsCommandList* This) return; } + + FrameGen_Dx12::ffxMutex.lock(); Config::Instance()->dxgiSkipSpoofing = true; retCode = FfxApiProxy::D3D12_Dispatch()(&FrameGen_Dx12::fgContext, &dfgPrepare.header); - fgDispatchCalled = true; Config::Instance()->dxgiSkipSpoofing = false; + FrameGen_Dx12::ffxMutex.unlock(); + + fgDispatchCalled = true; LOG_DEBUG("D3D12_Dispatch result: {0}, frame: {1}", retCode, frame); } } @@ -1496,17 +1498,24 @@ static void hkDispatch(ID3D12GraphicsCommandList* This, UINT ThreadGroupCountX, #pragma region Callbacks for wrapped swapchain +static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags) +{ + FrameGen_Dx12::ffxMutex.lock(); + LOG_DEBUG(""); + auto result = o_FGSCPresent(This, SyncInterval, Flags); + FrameGen_Dx12::ffxMutex.unlock(); + return result; +} + static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags, const DXGI_PRESENT_PARAMETERS* pPresentParameters, IUnknown* pDevice, HWND hWnd) { LOG_DEBUG(""); HRESULT presentResult; auto fIndex = fgFrameIndex; - + if (hWnd != Util::GetProcessWindow()) { - std::unique_lock lock(ffxMutex); - if (pPresentParameters == nullptr) presentResult = pSwapChain->Present(SyncInterval, Flags); else @@ -1577,8 +1586,6 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags if (device12 != nullptr) device12->Release(); - std::unique_lock lock(ffxMutex); - if (pPresentParameters == nullptr) presentResult = pSwapChain->Present(SyncInterval, Flags); else @@ -1678,8 +1685,6 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags frameCounter++; - std::unique_lock lock(ffxMutex); - // swapchain present if (pPresentParameters == nullptr) presentResult = pSwapChain->Present(SyncInterval, Flags); @@ -1876,6 +1881,27 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI if (result == FFX_API_RETURN_OK) { + // Hooking FG Swapchain present + // for using ffxMutex during calls + if (o_FGSCPresent == nullptr && *ppSwapChain != nullptr) + { + void** pFactoryVTable = *reinterpret_cast(*ppSwapChain); + + o_FGSCPresent = (PFN_Present)pFactoryVTable[8]; + + if (o_FGSCPresent != nullptr) + { + LOG_INFO("Hooking native FG SwapChain present"); + + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + DetourAttach(&(PVOID&)o_FGSCPresent, hkFGPresent); + + DetourTransactionCommit(); + } + } + scInfo.swapChainFormat = pDesc->BufferDesc.Format; scInfo.swapChainBufferCount = pDesc->BufferCount; scInfo.swapChain = (IDXGISwapChain4*)*ppSwapChain; @@ -2040,6 +2066,27 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H if (result == FFX_API_RETURN_OK) { + // Hooking FG Swapchain present + // for using ffxMutex during calls + if (o_FGSCPresent == nullptr && *ppSwapChain != nullptr) + { + void** pFactoryVTable = *reinterpret_cast(*ppSwapChain); + + o_FGSCPresent = (PFN_Present)pFactoryVTable[8]; + + if (o_FGSCPresent != nullptr) + { + LOG_INFO("Hooking native FG SwapChain present"); + + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + DetourAttach(&(PVOID&)o_FGSCPresent, hkFGPresent); + + DetourTransactionCommit(); + } + } + scInfo.swapChainFormat = pDesc->Format; scInfo.swapChainBufferCount = pDesc->BufferCount; scInfo.swapChain = (IDXGISwapChain4*)*ppSwapChain; @@ -2987,7 +3034,10 @@ void FrameGen_Dx12::ReleaseFGSwapchain(HWND hWnd) if (FrameGen_Dx12::fgSwapChainContext != nullptr) { + + FrameGen_Dx12::ffxMutex.lock(); auto result = FfxApiProxy::D3D12_DestroyContext()(&FrameGen_Dx12::fgSwapChainContext, nullptr); + FrameGen_Dx12::ffxMutex.unlock(); LOG_INFO("Destroy Ffx Swapchain Result: {}({})", result, FfxApiProxy::ReturnCodeToString(result)); FrameGen_Dx12::fgSwapChainContext = nullptr; fgSwapChains.erase(hWnd); diff --git a/OptiScaler/hooks/HooksDx.h b/OptiScaler/hooks/HooksDx.h index 39bb8c06..41be154e 100644 --- a/OptiScaler/hooks/HooksDx.h +++ b/OptiScaler/hooks/HooksDx.h @@ -8,7 +8,7 @@ #include #include -//#define ENABLE_DEBUG_LAYER +#define ENABLE_DEBUG_LAYER //#define ENABLE_GPU_VALIDATION #ifdef ENABLE_DEBUG_LAYER @@ -43,7 +43,6 @@ namespace HooksDx void HookDx11(); void HookDx12(); void HookDxgi(); - void HookSLDxgi(); } namespace FrameGen_Dx12 @@ -71,6 +70,10 @@ namespace FrameGen_Dx12 inline FT_Dx12* fgFormatTransfer = nullptr; inline bool fgIsActive = false; + // According to https://gpuopen.com/manuals/fidelityfx_sdk/fidelityfx_sdk-page_techniques_super-resolution-interpolation/#id11 + // will use this mutex to prevent race condutions + inline std::mutex ffxMutex; + UINT ClearFrameResources(); UINT GetFrame(); void NewFrame();