From aed7b1ff54887f610aee3d641306240c5c367eee Mon Sep 17 00:00:00 2001 From: cdozdil Date: Fri, 3 Oct 2025 18:52:08 +0300 Subject: [PATCH] Added check to prevent crashes at UpdateFFxApiProvider when using amd_fidelityfx_dx12.dll & amd_fidelityfx_framegeneration_dx12.dll combo --- OptiScaler/fsr4/FSR4Upgrade.cpp | 32 ++++++++++++++++++++- OptiScaler/proxies/FfxApi_Proxy.h | 47 +++++++++++++++---------------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/OptiScaler/fsr4/FSR4Upgrade.cpp b/OptiScaler/fsr4/FSR4Upgrade.cpp index 0f83dc99..075a3e76 100644 --- a/OptiScaler/fsr4/FSR4Upgrade.cpp +++ b/OptiScaler/fsr4/FSR4Upgrade.cpp @@ -171,6 +171,25 @@ void CheckForGPU() LOG_INFO("Fsr4Update: {}", Config::Instance()->Fsr4Update.value_or_default()); } +struct ffxProviderInterface +{ + uint64_t versionId; + const char* versionName; + PVOID canProvide; + PVOID createContext; + PVOID destroyContext; + PVOID configure; + PVOID query; + PVOID dispatch; +}; + +struct ExternalProviderData +{ + uint32_t structVersion = 2; + uint64_t descType; + ffxProviderInterface provider; +}; + struct AmdExtFfxApi : public IAmdExtFfxApi { PFN_UpdateFfxApiProvider o_UpdateFfxApiProvider = nullptr; @@ -179,6 +198,15 @@ struct AmdExtFfxApi : public IAmdExtFfxApi { LOG_INFO("UpdateFfxApiProvider called"); + // To prevent crashes with amd_fidelityfx_dx12.dll & amd_fidelityfx_framegeneration_dx12.dll combo added this + // check after ML FG update this should be disabled! + auto providerData = reinterpret_cast(pData); + if (providerData->descType >= 0x00020001u && providerData->descType <= 0x00030009u) + { + LOG_ERROR("Skip update for FG"); + return E_INVALIDARG; + } + if (o_UpdateFfxApiProvider == nullptr) { fsr4Module = NtdllProxy::LoadLibraryExW_Ldr(L"amdxcffx64.dll", NULL, 0); @@ -235,7 +263,9 @@ struct AmdExtFfxApi : public IAmdExtFfxApi if (o_UpdateFfxApiProvider != nullptr) { State::DisableChecks(1); + auto result = o_UpdateFfxApiProvider(pData, dataSizeInBytes); + LOG_INFO("UpdateFfxApiProvider called, result: {} ({:X})", result == S_OK ? "Ok" : "Error", (UINT) result); State::EnableChecks(1); return result; @@ -452,4 +482,4 @@ HRESULT STDMETHODCALLTYPE hkAmdExtD3DCreateInterface(IUnknown* pOuter, REFIID ri return o_AmdExtD3DCreateInterface(pOuter, riid, ppvObject); return E_NOINTERFACE; -} \ No newline at end of file +} diff --git a/OptiScaler/proxies/FfxApi_Proxy.h b/OptiScaler/proxies/FfxApi_Proxy.h index 1c849e4c..ba47161d 100644 --- a/OptiScaler/proxies/FfxApi_Proxy.h +++ b/OptiScaler/proxies/FfxApi_Proxy.h @@ -176,11 +176,8 @@ class FfxApiProxy } } - if (_D3D12_CreateContext == nullptr) - { - InitFfxDx12_SR(); - InitFfxDx12_FG(); - } + InitFfxDx12_SR(); + InitFfxDx12_FG(); bool loadResult = _D3D12_CreateContext != nullptr; @@ -545,6 +542,11 @@ class FfxApiProxy { auto isFg = IsFGType(desc->type); + if (isFg && _dllDx12_FG != nullptr) + return _D3D12_CreateContext_FG(context, desc, memCb); + else if (!isFg && _dllDx12_SR != nullptr) + return _D3D12_CreateContext_SR(context, desc, memCb); + if (_dllDx12 != nullptr && !(isFg && _skipFGCreateCalls) && !(!isFg && _skipSRCreateCalls)) { if (isFg) @@ -562,11 +564,6 @@ class FfxApiProxy return result; } - if (isFg && _dllDx12_FG != nullptr) - return _D3D12_CreateContext_FG(context, desc, memCb); - else if (!isFg && _dllDx12_SR != nullptr) - return _D3D12_CreateContext_SR(context, desc, memCb); - return FFX_API_RETURN_NO_PROVIDER; } @@ -603,6 +600,11 @@ class FfxApiProxy { auto isFg = IsFGType(desc->type); + if (isFg && _dllDx12_FG != nullptr) + return _D3D12_Configure_FG(context, desc); + else if (!isFg && _dllDx12_SR != nullptr) + return _D3D12_Configure_SR(context, desc); + if (_dllDx12 != nullptr && !(isFg && _skipFGConfigureCalls) && !(!isFg && _skipSRConfigureCalls)) { if (isFg) @@ -620,11 +622,6 @@ class FfxApiProxy return result; } - if (isFg && _dllDx12_FG != nullptr) - return _D3D12_Configure_FG(context, desc); - else if (!isFg && _dllDx12_SR != nullptr) - return _D3D12_Configure_SR(context, desc); - return FFX_API_RETURN_NO_PROVIDER; } @@ -632,6 +629,11 @@ class FfxApiProxy { auto isFg = IsFGType(desc->type); + if (isFg && _dllDx12_FG != nullptr) + return _D3D12_Query_FG(context, desc); + else if (!isFg && _dllDx12_SR != nullptr) + return _D3D12_Query_SR(context, desc); + if (_dllDx12 != nullptr && !(isFg && _skipFGQueryCalls) && !(!isFg && _skipSRQueryCalls)) { if (isFg) @@ -649,11 +651,6 @@ class FfxApiProxy return result; } - if (isFg && _dllDx12_FG != nullptr) - return _D3D12_Query_FG(context, desc); - else if (!isFg && _dllDx12_SR != nullptr) - return _D3D12_Query_SR(context, desc); - return FFX_API_RETURN_NO_PROVIDER; } @@ -661,6 +658,11 @@ class FfxApiProxy { auto isFg = IsFGType(desc->type); + if (isFg && _dllDx12_FG != nullptr) + return _D3D12_Dispatch_FG(context, desc); + else if (!isFg && _dllDx12_SR != nullptr) + return _D3D12_Dispatch_SR(context, desc); + if (_dllDx12 != nullptr && !(isFg && _skipFGDispatchCalls) && !(!isFg && _skipSRDispatchCalls)) { if (isFg) @@ -678,11 +680,6 @@ class FfxApiProxy return result; } - if (isFg && _dllDx12_FG != nullptr) - return _D3D12_Dispatch_FG(context, desc); - else if (!isFg && _dllDx12_SR != nullptr) - return _D3D12_Dispatch_SR(context, desc); - return FFX_API_RETURN_NO_PROVIDER; }