From b64da27a01ff468be8012ffc337e99fe875609f0 Mon Sep 17 00:00:00 2001 From: cdozdil Date: Sun, 29 Mar 2026 00:21:51 +0300 Subject: [PATCH] Better FG swapchain release --- OptiScaler/inputs/FG/FSR3_Dx12_FG.cpp | 31 +++++++++++++++++ OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp | 44 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/OptiScaler/inputs/FG/FSR3_Dx12_FG.cpp b/OptiScaler/inputs/FG/FSR3_Dx12_FG.cpp index bea277ef..3cf443c4 100644 --- a/OptiScaler/inputs/FG/FSR3_Dx12_FG.cpp +++ b/OptiScaler/inputs/FG/FSR3_Dx12_FG.cpp @@ -379,6 +379,21 @@ static Fsr3::FfxErrorCode hkffxCreateFrameinterpolationSwapchainDX12(DXGI_SWAP_C IDXGIFactory* dxgiFactory, Fsr3::FfxSwapchain& outGameSwapChain) { + if (State::Instance().currentSwapchain != nullptr && + State::Instance().currentSwapchainDesc.OutputWindow == desc->OutputWindow) + { + auto refCount = State::Instance().currentSwapchain->Release(); + + while (refCount > 0) + { + refCount = State::Instance().currentSwapchain->Release(); + } + + State::Instance().currentSwapchain = nullptr; + State::Instance().currentFGSwapchain = nullptr; + State::Instance().currentSwapchainDesc = {}; + } + auto result = dxgiFactory->CreateSwapChain(queue, desc, (IDXGISwapChain**) &outGameSwapChain); return result == S_OK ? Fsr3::FFX_OK : Fsr3::FFX_ERROR_BACKEND_API_ERROR; @@ -394,6 +409,22 @@ static Fsr3::FfxErrorCode hkffxCreateFrameinterpolationSwapchainForHwndDX12( if (dxgiFactory->QueryInterface(IID_PPV_ARGS(&df)) == S_OK) { df->Release(); + + if (State::Instance().currentSwapchain != nullptr && + State::Instance().currentSwapchainDesc.OutputWindow == hWnd) + { + auto refCount = State::Instance().currentSwapchain->Release(); + + while (refCount > 0) + { + refCount = State::Instance().currentSwapchain->Release(); + } + + State::Instance().currentSwapchain = nullptr; + State::Instance().currentFGSwapchain = nullptr; + State::Instance().currentSwapchainDesc = {}; + } + result = df->CreateSwapChainForHwnd(queue, hWnd, desc1, fullscreenDesc, nullptr, (IDXGISwapChain1**) &outGameSwapChain); } diff --git a/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp b/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp index c3d6d8f9..de35a56a 100644 --- a/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp +++ b/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp @@ -327,6 +327,22 @@ ffxReturnCode_t ffxCreateContext_Dx12FG(ffxContext* context, ffxCreateContextDes else if (desc->type == FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_NEW_DX12) { auto cDesc = (ffxCreateContextDescFrameGenerationSwapChainNewDX12*) desc; + + if (State::Instance().currentSwapchain != nullptr && + State::Instance().currentSwapchainDesc.OutputWindow == cDesc->desc->OutputWindow) + { + auto refCount = State::Instance().currentSwapchain->Release(); + + while (refCount > 0) + { + refCount = State::Instance().currentSwapchain->Release(); + } + + State::Instance().currentSwapchain = nullptr; + State::Instance().currentFGSwapchain = nullptr; + State::Instance().currentSwapchainDesc = {}; + } + auto result = cDesc->dxgiFactory->CreateSwapChain(cDesc->gameQueue, cDesc->desc, (IDXGISwapChain**) cDesc->swapchain); @@ -364,6 +380,21 @@ ffxReturnCode_t ffxCreateContext_Dx12FG(ffxContext* context, ffxCreateContextDes factory->Release(); + if (State::Instance().currentSwapchain != nullptr && + State::Instance().currentSwapchainDesc.OutputWindow == cDesc->hwnd) + { + auto refCount = State::Instance().currentSwapchain->Release(); + + while (refCount > 0) + { + refCount = State::Instance().currentSwapchain->Release(); + } + + State::Instance().currentSwapchain = nullptr; + State::Instance().currentFGSwapchain = nullptr; + State::Instance().currentSwapchainDesc = {}; + } + auto result = factory->CreateSwapChainForHwnd(cDesc->gameQueue, cDesc->hwnd, cDesc->desc, cDesc->fullscreenDesc, nullptr, (IDXGISwapChain1**) cDesc->swapchain); @@ -405,6 +436,19 @@ ffxReturnCode_t ffxDestroyContext_Dx12FG(ffxContext* context, const ffxAllocatio { LOG_INFO("Destroying Swapchain Context: {:X}", (size_t) State::Instance().currentFG); State::Instance().currentFG->ReleaseSwapchain(State::Instance().currentFG->Hwnd()); + + if (State::Instance().currentSwapchain != nullptr) + { + auto refCount = State::Instance().currentSwapchain->Release(); + + while (refCount > 0) + { + refCount = State::Instance().currentSwapchain->Release(); + } + + State::Instance().currentSwapchain = nullptr; + } + return FFX_API_RETURN_OK; } else if (State::Instance().currentFG != nullptr && (void*) fgContext == *context)