Improvements to FG swapchain release

This commit is contained in:
cdozdil
2026-03-06 01:44:33 +03:00
parent 4e6d8056ac
commit c000f65683
5 changed files with 36 additions and 8 deletions
+6 -2
View File
@@ -817,8 +817,12 @@ bool FSRFG_Dx12::ReleaseSwapchain(HWND hwnd)
if (_swapChainContext != nullptr)
{
auto result = FfxApiProxy::D3D12_DestroyContext(&_swapChainContext, nullptr);
LOG_INFO("Destroy Ffx Swapchain Result: {}({})", result, FfxApiProxy::ReturnCodeToString(result));
// Don't call D3D12_DestroyContext for swapchain context
// Most probably we are calling it from wrapped swapchain's Release which means that the swapchain is already
// destroyed and calling D3D12_DestroyContext will cause an error
// auto result = FfxApiProxy::D3D12_DestroyContext(&_swapChainContext, nullptr);
// LOG_INFO("Destroy Ffx Swapchain Result: {}({})", result, FfxApiProxy::ReturnCodeToString(result));
_swapChainContext = nullptr;
State::Instance().currentFGSwapchain = nullptr;
+6 -2
View File
@@ -1434,8 +1434,12 @@ bool XeFG_Dx12::ReleaseSwapchain(HWND hwnd)
if (_fgContext != nullptr)
DestroyFGContext();
if (State::Instance().isShuttingDown && _swapChainContext != nullptr)
DestroySwapchainContext();
// Don't call D3D12_DestroyContext for swapchain context
// Most probably we are calling it from wrapped swapchain's Release which means that the swapchain is already
// destroyed and calling D3D12_DestroyContext will cause an error
//
// if (State::Instance().isShuttingDown && _swapChainContext != nullptr)
// DestroySwapchainContext();
ReleaseObjects();
+21 -3
View File
@@ -975,10 +975,28 @@ HRESULT FGHooks::hkFGRelease(IDXGISwapChain* This)
return o_FGRelease(This);
This->AddRef();
if (o_FGRelease(This) == 1)
if (State::Instance().gameQuirks & GameQuirk::DoNotPreserveFGSwapChain)
{
LOG_INFO("Preserving FG Swapchain from release");
return 0;
if (o_FGRelease(This) == 1)
{
if (State::Instance().currentFG != nullptr)
{
LOG_DEBUG("FG Swapchain released, deactivating FG");
State::Instance().currentFG->Deactivate();
}
LOG_DEBUG("FG Swapchain released, clearing currentFGSwapchain");
State::Instance().currentFGSwapchain = nullptr;
}
}
else
{
if (o_FGRelease(This) == 1)
{
LOG_INFO("Preserving FG Swapchain from release");
return 0;
}
}
return o_FGRelease(This);
+2 -1
View File
@@ -56,6 +56,7 @@ enum class GameQuirk : uint64_t
CreateD3D12DeviceForLuma,
ForceCreateD3D12Device,
ForceDepthD32S8,
DoNotPreserveFGSwapChain,
// Don't forget to add the new entry to printQuirks
_
};
@@ -118,7 +119,7 @@ static const QuirkEntry quirkTable[] = {
QUIRK_ENTRY("sora_1st.exe", GameQuirk::UseFsr2Dx11Inputs, GameQuirk::DisableDxgiSpoofing),
// Ninja Gaiden 4 (Steam)
QUIRK_ENTRY("ninjagaiden4-steam.exe", GameQuirk::DisableResizeSkip),
QUIRK_ENTRY("ninjagaiden4-steam.exe", GameQuirk::DisableResizeSkip, GameQuirk::DoNotPreserveFGSwapChain),
// The Last of Us Part I
QUIRK_ENTRY("tlou-i.exe", GameQuirk::AllowedFrameAhead2),
+1
View File
@@ -431,6 +431,7 @@ ULONG STDMETHODCALLTYPE WrappedIDXGISwapChain4::Release()
auto fg = State::Instance().currentFG;
if (fg != nullptr && fg->Mutex.getOwner() != 1 && fg->SwapchainContext() != nullptr)
{
fg->Deactivate();
fg->ReleaseSwapchain(_handle);
if (State::Instance().currentFGSwapchain != nullptr)