diff --git a/OptiScaler/NVNGX_DLSS_Dx12.cpp b/OptiScaler/NVNGX_DLSS_Dx12.cpp index d99acdb8..20cb2716 100644 --- a/OptiScaler/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/NVNGX_DLSS_Dx12.cpp @@ -1184,10 +1184,11 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom { if (!Config::Instance()->FGChanged && FrameGen_Dx12::fgTarget < deviceContext->FrameCount() && Config::Instance()->FGEnabled.value_or(false) && FfxApiProxy::InitFfxDx12() && !FrameGen_Dx12::fgIsActive && HooksDx::currentSwapchain != nullptr && - HooksDx::swapchainFormat != DXGI_FORMAT_UNKNOWN) + HooksDx::CurrentSwapchainFormat() != DXGI_FORMAT_UNKNOWN) { FrameGen_Dx12::CreateFGObjects(D3D12Device); FrameGen_Dx12::CreateFGContext(D3D12Device, deviceContext); + FrameGen_Dx12::fgTarget = deviceContext->FrameCount() + 3; } else if ((!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged) && FrameGen_Dx12::fgIsActive) { @@ -1212,7 +1213,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom UINT frameIndex; if (FrameGen_Dx12::fgIsActive && Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true) && - Config::Instance()->FGEnabled.value_or(false) && FrameGen_Dx12::fgTarget < deviceContext->FrameCount() && + Config::Instance()->FGEnabled.value_or(false) && FrameGen_Dx12::fgTarget <= deviceContext->FrameCount() && FrameGen_Dx12::fgContext != nullptr && HooksDx::currentSwapchain != nullptr) { frameIndex = FrameGen_Dx12::ClearFrameResources(); @@ -1317,13 +1318,14 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom if (evalResult) { HooksDx::dx12UpscaleTrig = true; - FrameGen_Dx12::upscaleRan = true; // FG Dispatch if (FrameGen_Dx12::fgIsActive && Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true) && Config::Instance()->FGEnabled.value_or(false) && FrameGen_Dx12::fgTarget < deviceContext->FrameCount() && FrameGen_Dx12::fgContext != nullptr && HooksDx::currentSwapchain != nullptr) { + FrameGen_Dx12::upscaleRan = true; + float msDelta = 0.0; auto now = Util::MillisecondsNow(); @@ -1345,7 +1347,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom ffxConfigureDescFrameGeneration m_FrameGenerationConfig = {}; - if (desc.Format == HooksDx::swapchainFormat) + if (desc.Format == HooksDx::CurrentSwapchainFormat()) { LOG_DEBUG("(FG) desc.Format == HooksDx::swapchainFormat, using for hudless!"); m_FrameGenerationConfig.HUDLessColor = ffxApiGetResourceDX12(output, FFX_API_RESOURCE_STATE_UNORDERED_ACCESS, 0); @@ -1412,7 +1414,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,11 +1537,15 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom dfgPrepare.viewSpaceToMetersFactor = 1.0; dfgPrepare.frameTimeDelta = msDelta; +#ifdef USE_MUTEX_FOR_FFX FrameGen_Dx12::ffxMutex.lock(); +#endif Config::Instance()->dxgiSkipSpoofing = true; retCode = FfxApiProxy::D3D12_Dispatch()(&FrameGen_Dx12::fgContext, &dfgPrepare.header); Config::Instance()->dxgiSkipSpoofing = false; +#ifdef USE_MUTEX_FOR_FFX FrameGen_Dx12::ffxMutex.unlock(); +#endif 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 1b5d23cf..ced371a5 100644 --- a/OptiScaler/hooks/HooksDx.cpp +++ b/OptiScaler/hooks/HooksDx.cpp @@ -598,12 +598,15 @@ static void GetHudless(ID3D12GraphicsCommandList* This) } +#ifdef USE_MUTEX_FOR_FFX FrameGen_Dx12::ffxMutex.lock(); +#endif Config::Instance()->dxgiSkipSpoofing = true; retCode = FfxApiProxy::D3D12_Dispatch()(&FrameGen_Dx12::fgContext, &dfgPrepare.header); Config::Instance()->dxgiSkipSpoofing = false; +#ifdef USE_MUTEX_FOR_FFX FrameGen_Dx12::ffxMutex.unlock(); - +#endif fgDispatchCalled = true; LOG_DEBUG("D3D12_Dispatch result: {0}, frame: {1}", retCode, frame); } @@ -703,7 +706,7 @@ static bool CheckForHudless(std::string callerName, ResourceInfo* resource) return false; } - if ((scDesc.BufferDesc.Height != fgScDesc.BufferDesc.Height || scDesc.BufferDesc.Width != fgScDesc.BufferDesc.Width || scDesc.BufferDesc.Format != fgScDesc.BufferDesc.Format)) + if (scDesc.BufferDesc.Format != FrameGen_Dx12::fgFormatTransfer->Format()) { LOG_DEBUG("Format change, recreate the FormatTransfer"); @@ -712,8 +715,10 @@ static bool CheckForHudless(std::string callerName, ResourceInfo* resource) FrameGen_Dx12::fgFormatTransfer = nullptr; FrameGen_Dx12::fgFormatTransfer = new FT_Dx12("FormatTransfer", g_pd3dDeviceParam, scDesc.BufferDesc.Format); + } - HooksDx::swapchainFormat = scDesc.BufferDesc.Format; + if ((scDesc.BufferDesc.Height != fgScDesc.BufferDesc.Height || scDesc.BufferDesc.Width != fgScDesc.BufferDesc.Width || scDesc.BufferDesc.Format != fgScDesc.BufferDesc.Format)) + { fgScDesc = scDesc; } @@ -1498,6 +1503,7 @@ static void hkDispatch(ID3D12GraphicsCommandList* This, UINT ThreadGroupCountX, #pragma region Callbacks for wrapped swapchain +#ifdef USE_MUTEX_FOR_FFX static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags) { FrameGen_Dx12::ffxMutex.lock(); @@ -1506,6 +1512,7 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags) FrameGen_Dx12::ffxMutex.unlock(); return result; } +#endif static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags, const DXGI_PRESENT_PARAMETERS* pPresentParameters, IUnknown* pDevice, HWND hWnd) { @@ -1522,7 +1529,6 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags presentResult = ((IDXGISwapChain1*)pSwapChain)->Present1(SyncInterval, Flags, pPresentParameters); HooksDx::currentSwapchain = nullptr; - HooksDx::swapchainFormat = DXGI_FORMAT_UNKNOWN; FrameGen_Dx12::fgSkipHudlessChecks = false; LOG_FUNC_RESULT(presentResult); @@ -1534,9 +1540,6 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags auto swInfo = &fgSwapChains[hWnd]; HooksDx::currentSwapchain = swInfo->swapChain; - if (HooksDx::swapchainFormat == DXGI_FORMAT_UNKNOWN) - HooksDx::swapchainFormat = swInfo->swapChainFormat; - swInfo->fgCommandQueue = (ID3D12CommandQueue*)pDevice; FrameGen_Dx12::gameCommandQueue = swInfo->gameCommandQueue; } @@ -1881,6 +1884,7 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI if (result == FFX_API_RETURN_OK) { +#ifdef USE_MUTEX_FOR_FFX // Hooking FG Swapchain present // for using ffxMutex during calls if (o_FGSCPresent == nullptr && *ppSwapChain != nullptr) @@ -1901,7 +1905,7 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI DetourTransactionCommit(); } } - +#endif scInfo.swapChainFormat = pDesc->BufferDesc.Format; scInfo.swapChainBufferCount = pDesc->BufferCount; scInfo.swapChain = (IDXGISwapChain4*)*ppSwapChain; @@ -2066,6 +2070,7 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H if (result == FFX_API_RETURN_OK) { +#ifdef USE_MUTEX_FOR_FFX // Hooking FG Swapchain present // for using ffxMutex during calls if (o_FGSCPresent == nullptr && *ppSwapChain != nullptr) @@ -2086,6 +2091,7 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H DetourTransactionCommit(); } } +#endif scInfo.swapChainFormat = pDesc->Format; scInfo.swapChainBufferCount = pDesc->BufferCount; @@ -2718,12 +2724,11 @@ static HRESULT hkD3D12CreateDevice(IDXGIAdapter* pAdapter, D3D_FEATURE_LEVEL Min infoQueue->SetMuteDebugOutput(false); HRESULT res; - //res = infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE); //res = infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE); //res = infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE); - if (infoQueue->QueryInterface(IID_PPV_ARGS(&infoQueue1)) == S_OK) + if (infoQueue->QueryInterface(IID_PPV_ARGS(&infoQueue1)) == S_OK && infoQueue1 != nullptr) { LOG_DEBUG("infoQueue1 accuired, registering MessageCallback"); res = infoQueue1->RegisterMessageCallback(D3D12DebugCallback, D3D12_MESSAGE_CALLBACK_IGNORE_FILTERS, NULL, NULL); @@ -2926,6 +2931,18 @@ void HooksDx::HookDxgi() } } +DXGI_FORMAT HooksDx::CurrentSwapchainFormat() +{ + if (HooksDx::currentSwapchain == nullptr) + return DXGI_FORMAT_UNKNOWN; + + DXGI_SWAP_CHAIN_DESC scDesc{}; + if (HooksDx::currentSwapchain->GetDesc(&scDesc) != S_OK) + return DXGI_FORMAT_UNKNOWN; + + return scDesc.BufferDesc.Format; +} + void HooksDx::UnHookDx() { DetourTransactionBegin(); @@ -3034,10 +3051,13 @@ void FrameGen_Dx12::ReleaseFGSwapchain(HWND hWnd) if (FrameGen_Dx12::fgSwapChainContext != nullptr) { - +#ifdef USE_MUTEX_FOR_FFX FrameGen_Dx12::ffxMutex.lock(); +#endif auto result = FfxApiProxy::D3D12_DestroyContext()(&FrameGen_Dx12::fgSwapChainContext, nullptr); +#ifdef USE_MUTEX_FOR_FFX FrameGen_Dx12::ffxMutex.unlock(); +#endif LOG_INFO("Destroy Ffx Swapchain Result: {}({})", result, FfxApiProxy::ReturnCodeToString(result)); FrameGen_Dx12::fgSwapChainContext = nullptr; fgSwapChains.erase(hWnd); @@ -3136,7 +3156,7 @@ void FrameGen_Dx12::CreateFGObjects(ID3D12Device* InDevice) } FrameGen_Dx12::fgCopyCommandQueue->SetName(L"fgCopyCommandQueue"); - FrameGen_Dx12::fgFormatTransfer = new FT_Dx12("FormatTransfer", InDevice, HooksDx::swapchainFormat); + FrameGen_Dx12::fgFormatTransfer = new FT_Dx12("FormatTransfer", InDevice, HooksDx::CurrentSwapchainFormat()); } while (false); } @@ -3199,7 +3219,8 @@ void FrameGen_Dx12::CreateFGContext(ID3D12Device* InDevice, IFeature* deviceCont if (Config::Instance()->FGAsync.value_or(false)) createFg.flags |= FFX_FRAMEGENERATION_ENABLE_ASYNC_WORKLOAD_SUPPORT; - createFg.backBufferFormat = ffxApiGetSurfaceFormatDX12(HooksDx::swapchainFormat); + + createFg.backBufferFormat = ffxApiGetSurfaceFormatDX12(HooksDx::CurrentSwapchainFormat()); createFg.header.pNext = &backendDesc.header; Config::Instance()->dxgiSkipSpoofing = true; diff --git a/OptiScaler/hooks/HooksDx.h b/OptiScaler/hooks/HooksDx.h index 41be154e..ce69b697 100644 --- a/OptiScaler/hooks/HooksDx.h +++ b/OptiScaler/hooks/HooksDx.h @@ -8,10 +8,12 @@ #include #include -#define ENABLE_DEBUG_LAYER -//#define ENABLE_GPU_VALIDATION +#define USE_MUTEX_FOR_FFX +//#define ENABLE_DEBUG_LAYER #ifdef ENABLE_DEBUG_LAYER +//#define ENABLE_GPU_VALIDATION + #include #endif @@ -34,7 +36,6 @@ namespace HooksDx inline ID3D12CommandQueue* GameCommandQueue = nullptr; inline IDXGISwapChain* currentSwapchain = nullptr; - inline DXGI_FORMAT swapchainFormat = DXGI_FORMAT_UNKNOWN; inline int currentFrameIndex = 0; inline int previousFrameIndex = 0; @@ -43,6 +44,7 @@ namespace HooksDx void HookDx11(); void HookDx12(); void HookDxgi(); + DXGI_FORMAT CurrentSwapchainFormat(); } namespace FrameGen_Dx12 @@ -70,9 +72,11 @@ namespace FrameGen_Dx12 inline FT_Dx12* fgFormatTransfer = nullptr; inline bool fgIsActive = false; +#ifdef USE_MUTEX_FOR_FFX // 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; +#endif UINT ClearFrameResources(); UINT GetFrame(); diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index df1db279..8e70454d 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -21,7 +21,7 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 7 #define VER_HOTFIX_VERSION 0 -#define VER_BUILD_NUMBER 32 +#define VER_BUILD_NUMBER 33 #define VER_PRE_RELEASE