More FG swapchain release improvements

This commit is contained in:
cdozdil
2026-03-29 20:45:42 +03:00
parent 1e25b51930
commit b09abb6bd6
3 changed files with 38 additions and 59 deletions
+12 -26
View File
@@ -26,7 +26,6 @@
inline static ID3D12Fence* resizeFence = nullptr;
inline static UINT64 resizeFenceValue = 0;
inline static HANDLE resizeFenceEvent = nullptr;
inline static bool readyToRelease = false;
inline static IUnknown* oldSwapChain = nullptr;
#if (XEFG_RESOURCE_REF_LIMIT == 0)
@@ -139,9 +138,9 @@ HRESULT FGHooks::CreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI
// Looks like game is creating new swapchain,
// without releasing old one, be sure gpu is in idle state
if (readyToRelease && State::Instance().currentFGSwapchain != nullptr)
if (State::Instance().currentFGSwapchain != nullptr)
{
LOG_DEBUG("Ready to release: {}", readyToRelease);
LOG_WARN("Looks like game is creating new swapchain, without releasing old one!");
if (State::Instance().currentCommandQueue != nullptr && resizeFence != nullptr &&
resizeFenceEvent != nullptr)
@@ -163,7 +162,7 @@ HRESULT FGHooks::CreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI
oldSwapChain = State::Instance().currentFGSwapchain;
}
scResult = fg->CreateSwapchain(pFactory, cq, pDesc, ppSwapChain, readyToRelease);
scResult = fg->CreateSwapchain(pFactory, cq, pDesc, ppSwapChain, true);
if (Config::Instance()->FGDontUseSwapchainBuffers.value_or_default())
State::Instance().skipHeapCapture = false;
@@ -171,8 +170,6 @@ HRESULT FGHooks::CreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI
if (scResult)
{
readyToRelease = false;
if (State::Instance().currentD3D12Device != nullptr)
{
if (resizeFence != nullptr)
@@ -268,8 +265,10 @@ HRESULT FGHooks::CreateSwapChainForHwnd(IDXGIFactory* pFactory, IUnknown* pDevic
// Looks like game is creating new swapchain,
// without releasing old one, be sure gpu is in idle state
if (readyToRelease && State::Instance().currentFGSwapchain != nullptr)
if (State::Instance().currentFGSwapchain != nullptr)
{
LOG_WARN("Looks like game is creating new swapchain, without releasing old one!");
if (State::Instance().currentCommandQueue != nullptr && resizeFence != nullptr &&
resizeFenceEvent != nullptr)
{
@@ -290,7 +289,7 @@ HRESULT FGHooks::CreateSwapChainForHwnd(IDXGIFactory* pFactory, IUnknown* pDevic
oldSwapChain = State::Instance().currentFGSwapchain;
}
scResult = fg->CreateSwapchain1(pFactory, cq, hWnd, pDesc, pFullscreenDesc, ppSwapChain, readyToRelease);
scResult = fg->CreateSwapchain1(pFactory, cq, hWnd, pDesc, pFullscreenDesc, ppSwapChain, true);
if (Config::Instance()->FGDontUseSwapchainBuffers.value_or_default())
State::Instance().skipHeapCapture = false;
@@ -298,8 +297,6 @@ HRESULT FGHooks::CreateSwapChainForHwnd(IDXGIFactory* pFactory, IUnknown* pDevic
if (scResult)
{
readyToRelease = false;
if (State::Instance().currentD3D12Device != nullptr)
{
if (resizeFence != nullptr)
@@ -436,16 +433,6 @@ HRESULT FGHooks::hkSetFullscreenState(IDXGISwapChain* This, BOOL Fullscreen, IDX
LOG_DEBUG("Fullscreen: {}, pTarget: {:X}, Result: {:X}", Fullscreen, (size_t) pTarget, (UINT) result);
}
// Setting Fullscreen to false and pTarget to null
// releases internal buffers, so game might create a swapchain
// for same hwnd without releasing old one
readyToRelease = false;
if (result == S_OK && !orgFS && pTarget == NULL)
{
LOG_DEBUG("Ready to release is set");
readyToRelease = true;
}
if (result == S_OK && modeChanged)
{
LOG_DEBUG("Mode changed");
@@ -1280,18 +1267,17 @@ ULONG FGHooks::hkFGRelease(IUnknown* This)
LOG_DEBUG("FG Swapchain released, clearing currentFGSwapchain");
State::Instance().currentFGSwapchain = nullptr;
if (State::Instance().currentSwapchain != nullptr &&
if (State::Instance().currentWrappedSwapchain != nullptr &&
State::Instance().currentSwapchainDesc.OutputWindow == _hwnd)
{
auto refCount = State::Instance().currentSwapchain->Release();
auto refCount = State::Instance().currentWrappedSwapchain->Release();
while (refCount > 0 && refCount != 0xffffffff)
while (refCount > 0 && refCount < 0xffffff00)
{
refCount = State::Instance().currentSwapchain->Release();
refCount = State::Instance().currentWrappedSwapchain->Release();
}
State::Instance().currentSwapchain = nullptr;
State::Instance().currentSwapchainDesc = {};
State::Instance().currentWrappedSwapchain = nullptr;
}
skipReleaseChecks = false;
+10 -14
View File
@@ -379,19 +379,17 @@ static Fsr3::FfxErrorCode hkffxCreateFrameinterpolationSwapchainDX12(DXGI_SWAP_C
IDXGIFactory* dxgiFactory,
Fsr3::FfxSwapchain& outGameSwapChain)
{
if (State::Instance().currentSwapchain != nullptr &&
if (State::Instance().currentWrappedSwapchain != nullptr &&
State::Instance().currentSwapchainDesc.OutputWindow == desc->OutputWindow)
{
auto refCount = State::Instance().currentSwapchain->Release();
auto refCount = State::Instance().currentWrappedSwapchain->Release();
while (refCount > 0 && refCount != 0xffffffff)
while (refCount > 0 && refCount < 0xffffff00)
{
refCount = State::Instance().currentSwapchain->Release();
refCount = State::Instance().currentWrappedSwapchain->Release();
}
State::Instance().currentSwapchain = nullptr;
State::Instance().currentFGSwapchain = nullptr;
State::Instance().currentSwapchainDesc = {};
State::Instance().currentWrappedSwapchain = nullptr;
}
auto result = dxgiFactory->CreateSwapChain(queue, desc, (IDXGISwapChain**) &outGameSwapChain);
@@ -410,19 +408,17 @@ static Fsr3::FfxErrorCode hkffxCreateFrameinterpolationSwapchainForHwndDX12(
{
df->Release();
if (State::Instance().currentSwapchain != nullptr &&
if (State::Instance().currentWrappedSwapchain != nullptr &&
State::Instance().currentSwapchainDesc.OutputWindow == hWnd)
{
auto refCount = State::Instance().currentSwapchain->Release();
auto refCount = State::Instance().currentWrappedSwapchain->Release();
while (refCount > 0 && refCount != 0xffffffff)
while (refCount > 0 && refCount < 0xffffff00)
{
refCount = State::Instance().currentSwapchain->Release();
refCount = State::Instance().currentWrappedSwapchain->Release();
}
State::Instance().currentSwapchain = nullptr;
State::Instance().currentFGSwapchain = nullptr;
State::Instance().currentSwapchainDesc = {};
State::Instance().currentWrappedSwapchain = nullptr;
}
result = df->CreateSwapChainForHwnd(queue, hWnd, desc1, fullscreenDesc, nullptr,
+16 -19
View File
@@ -328,19 +328,17 @@ ffxReturnCode_t ffxCreateContext_Dx12FG(ffxContext* context, ffxCreateContextDes
{
auto cDesc = (ffxCreateContextDescFrameGenerationSwapChainNewDX12*) desc;
if (State::Instance().currentSwapchain != nullptr &&
if (State::Instance().currentWrappedSwapchain != nullptr &&
State::Instance().currentSwapchainDesc.OutputWindow == cDesc->desc->OutputWindow)
{
auto refCount = State::Instance().currentSwapchain->Release();
auto refCount = State::Instance().currentWrappedSwapchain->Release();
while (refCount > 0 && refCount != 0xffffffff)
while (refCount > 0 && refCount < 0xffffff00)
{
refCount = State::Instance().currentSwapchain->Release();
refCount = State::Instance().currentWrappedSwapchain->Release();
}
State::Instance().currentSwapchain = nullptr;
State::Instance().currentFGSwapchain = nullptr;
State::Instance().currentSwapchainDesc = {};
State::Instance().currentWrappedSwapchain = nullptr;
}
auto result =
@@ -380,19 +378,17 @@ ffxReturnCode_t ffxCreateContext_Dx12FG(ffxContext* context, ffxCreateContextDes
factory->Release();
if (State::Instance().currentSwapchain != nullptr &&
if (State::Instance().currentWrappedSwapchain != nullptr &&
State::Instance().currentSwapchainDesc.OutputWindow == cDesc->hwnd)
{
auto refCount = State::Instance().currentSwapchain->Release();
auto refCount = State::Instance().currentWrappedSwapchain->Release();
while (refCount > 0 && refCount != 0xffffffff)
while (refCount > 0 && refCount < 0xffffff00)
{
refCount = State::Instance().currentSwapchain->Release();
refCount = State::Instance().currentWrappedSwapchain->Release();
}
State::Instance().currentSwapchain = nullptr;
State::Instance().currentFGSwapchain = nullptr;
State::Instance().currentSwapchainDesc = {};
State::Instance().currentWrappedSwapchain = nullptr;
}
auto result = factory->CreateSwapChainForHwnd(cDesc->gameQueue, cDesc->hwnd, cDesc->desc, cDesc->fullscreenDesc,
@@ -437,16 +433,17 @@ 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)
if (State::Instance().currentWrappedSwapchain != nullptr &&
State::Instance().currentSwapchainDesc.OutputWindow == State::Instance().currentFG->Hwnd())
{
auto refCount = State::Instance().currentSwapchain->Release();
auto refCount = State::Instance().currentWrappedSwapchain->Release();
while (refCount > 0 && refCount != 0xffffffff)
while (refCount > 0 && refCount < 0xffffff00)
{
refCount = State::Instance().currentSwapchain->Release();
refCount = State::Instance().currentWrappedSwapchain->Release();
}
State::Instance().currentSwapchain = nullptr;
State::Instance().currentWrappedSwapchain = nullptr;
}
return FFX_API_RETURN_OK;