Passthrough FSRD calls

This commit is contained in:
FakeMichau
2026-03-22 16:36:36 +01:00
parent 5cd6907d96
commit d9a8ff8fe4
3 changed files with 168 additions and 21 deletions
+1
View File
@@ -201,6 +201,7 @@ DEFINE_NAME_VECTORS(fsr3BE, "ffx_backend_dx12_x64");
DEFINE_NAME_VECTORS(ffxDx12, "amd_fidelityfx_dx12", "amd_fidelityfx_loader_dx12");
DEFINE_NAME_VECTORS(ffxDx12Upscaler, "amd_fidelityfx_upscaler_dx12");
DEFINE_NAME_VECTORS(ffxDx12FG, "amd_fidelityfx_framegeneration_dx12");
DEFINE_NAME_VECTORS(ffxDx12Denoiser, "amd_fidelityfx_denoiser_dx12");
DEFINE_NAME_VECTORS(ffxVk, "amd_fidelityfx_vk");
inline static bool CompareFileName(std::string* first, std::string* second)
+8
View File
@@ -989,6 +989,14 @@ static void CheckWorkingMode()
FfxApiProxy::InitFfxDx12_FG(ffxDx12FGModule);
}
HMODULE ffxDx12DenoiserModule = nullptr;
ffxDx12DenoiserModule = GetDllNameWModule(&ffxDx12DenoiserNamesW);
if (ffxDx12DenoiserModule != nullptr)
{
LOG_DEBUG("amd_fidelityfx_denoiser_dx12.dll already in memory");
FfxApiProxy::InitFfxDx12_Denoiser(ffxDx12FGModule);
}
// FFX Vulkan
HMODULE ffxVkModule = nullptr;
ffxVkModule = GetDllNameWModule(&ffxVkNamesW);
+159 -21
View File
@@ -75,6 +75,7 @@ class FfxApiProxy
inline static FfxModule main_dx12;
inline static FfxModule upscaling_dx12;
inline static FfxModule fg_dx12;
inline static FfxModule denoiser_dx12;
inline static FfxModule main_vk;
@@ -94,6 +95,7 @@ class FfxApiProxy
static HMODULE Dx12Module() { return main_dx12.dll; }
static HMODULE Dx12Module_SR() { return upscaling_dx12.dll; }
static HMODULE Dx12Module_FG() { return fg_dx12.dll; }
static HMODULE Dx12Module_Denoiser() { return denoiser_dx12.dll; }
static bool IsFGReady()
{
@@ -117,6 +119,17 @@ class FfxApiProxy
return result;
}
static bool IsDenoiserReady()
{
bool result = (main_dx12.dll && !main_dx12.isLoader) || denoiser_dx12.dll != nullptr;
if (!result)
ImGui::InsertNotification({ ImGuiToastType::Error, 10000,
"Can't load amd_fidelityfx_dx12\nDid you forget to extract that dll?" });
return result;
}
static FFXStructType GetType(ffxStructType_t type)
{
switch (type & FFX_API_EFFECT_MASK) // type without the specific effect
@@ -267,9 +280,10 @@ class FfxApiProxy
InitFfxDx12_SR();
InitFfxDx12_FG();
InitFfxDx12_Denoiser();
bool loadResult = main_dx12.CreateContext != nullptr || upscaling_dx12.CreateContext != nullptr ||
fg_dx12.CreateContext != nullptr;
fg_dx12.CreateContext != nullptr || denoiser_dx12.CreateContext != nullptr;
LOG_INFO("LoadResult: {}", loadResult);
@@ -474,6 +488,104 @@ class FfxApiProxy
return loadResult;
}
static bool InitFfxDx12_Denoiser(HMODULE module = nullptr)
{
// if dll already loaded
if (denoiser_dx12.dll != nullptr && denoiser_dx12.CreateContext != nullptr)
return true;
spdlog::info("");
if (module != nullptr)
denoiser_dx12.dll = module;
if (denoiser_dx12.dll == nullptr)
{
// Try new api first
std::vector<std::wstring> dllNames = { L"amd_fidelityfx_denoiser_dx12.dll" };
for (size_t i = 0; i < dllNames.size(); i++)
{
LOG_DEBUG("Trying to load {}", wstring_to_string(dllNames[i]));
// if (denoiser_dx12.dll == nullptr && Config::Instance()->FfxDx12Path.has_value())
//{
// std::filesystem::path libPath(Config::Instance()->FfxDx12Path.value().c_str());
// if (libPath.has_filename())
// denoiser_dx12.dll = NtdllProxy::LoadLibraryExW_Ldr(libPath.c_str(), NULL, 0);
// else
// denoiser_dx12.dll = NtdllProxy::LoadLibraryExW_Ldr((libPath / dllNames[i]).c_str(), NULL, 0);
// if (denoiser_dx12.dll != nullptr)
// {
// LOG_INFO("{} loaded from {}", wstring_to_string(dllNames[i]),
// wstring_to_string(Config::Instance()->FfxDx12Path.value()));
// break;
// }
//}
if (denoiser_dx12.dll == nullptr)
{
denoiser_dx12.dll = NtdllProxy::LoadLibraryExW_Ldr(dllNames[i].c_str(), NULL, 0);
if (denoiser_dx12.dll != nullptr)
{
LOG_INFO("{} loaded from exe folder", wstring_to_string(dllNames[i]));
break;
}
}
}
}
if (denoiser_dx12.dll != nullptr && denoiser_dx12.Configure == nullptr)
{
denoiser_dx12.Configure =
(PfnFfxConfigure) KernelBaseProxy::GetProcAddress_()(denoiser_dx12.dll, "ffxConfigure");
denoiser_dx12.CreateContext =
(PfnFfxCreateContext) KernelBaseProxy::GetProcAddress_()(denoiser_dx12.dll, "ffxCreateContext");
denoiser_dx12.DestroyContext =
(PfnFfxDestroyContext) KernelBaseProxy::GetProcAddress_()(denoiser_dx12.dll, "ffxDestroyContext");
denoiser_dx12.Dispatch =
(PfnFfxDispatch) KernelBaseProxy::GetProcAddress_()(denoiser_dx12.dll, "ffxDispatch");
denoiser_dx12.Query = (PfnFfxQuery) KernelBaseProxy::GetProcAddress_()(denoiser_dx12.dll, "ffxQuery");
if (Config::Instance()->EnableFfxInputs.value_or_default() && denoiser_dx12.CreateContext != nullptr)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (denoiser_dx12.Configure != nullptr)
DetourAttach(&(PVOID&) denoiser_dx12.Configure, ffxConfigure_Dx12);
if (denoiser_dx12.CreateContext != nullptr)
DetourAttach(&(PVOID&) denoiser_dx12.CreateContext, ffxCreateContext_Dx12);
if (denoiser_dx12.DestroyContext != nullptr)
DetourAttach(&(PVOID&) denoiser_dx12.DestroyContext, ffxDestroyContext_Dx12);
if (denoiser_dx12.Dispatch != nullptr)
DetourAttach(&(PVOID&) denoiser_dx12.Dispatch, ffxDispatch_Dx12);
if (denoiser_dx12.Query != nullptr)
DetourAttach(&(PVOID&) denoiser_dx12.Query, ffxQuery_Dx12);
State::Instance().fsrHooks = true;
DetourTransactionCommit();
}
}
bool loadResult = denoiser_dx12.CreateContext != nullptr;
LOG_INFO("LoadResult: {}", loadResult);
if (!loadResult)
denoiser_dx12.dll = nullptr;
return loadResult;
}
static feature_version VersionDx12()
{
if (main_dx12.version.major == 0 && main_dx12.Query != nullptr /* && device != nullptr*/)
@@ -637,27 +749,34 @@ class FfxApiProxy
LOG_DEBUG("Creating with fg_dx12");
return fg_dx12.CreateContext(context, desc, memCb);
}
else if (!isFg && upscaling_dx12.dll != nullptr)
else if (type == FFXStructType::Upscaling && upscaling_dx12.dll != nullptr)
{
LOG_DEBUG("Creating with upscaling_dx12");
return upscaling_dx12.CreateContext(context, desc, memCb);
}
else if (type == FFXStructType::Denoiser && denoiser_dx12.dll != nullptr)
{
LOG_DEBUG("Creating with denoiser_dx12");
return denoiser_dx12.CreateContext(context, desc, memCb);
}
if (main_dx12.dll != nullptr && !(isFg && fg_dx12.skipCreateCalls) &&
!(!isFg && upscaling_dx12.skipCreateCalls))
const auto skipFG = isFg && fg_dx12.skipQueryCalls;
const auto skipUpscaling = type == FFXStructType::Upscaling && upscaling_dx12.skipQueryCalls;
if (main_dx12.dll != nullptr && !skipFG && !skipUpscaling)
{
LOG_DEBUG("Creating with main_dx12");
if (isFg)
fg_dx12.skipCreateCalls = true;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipCreateCalls = true;
auto result = main_dx12.CreateContext(context, desc, memCb);
if (isFg)
fg_dx12.skipCreateCalls = false;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipCreateCalls = false;
return result;
@@ -673,8 +792,8 @@ class FfxApiProxy
if (contextToType.contains(context))
{
LOG_DEBUG("Found context type mapping: {}", magic_enum::enum_name(type));
type = contextToType[context];
LOG_DEBUG("Found context type mapping: {}", magic_enum::enum_name(type));
contextToType.erase(context);
}
else
@@ -703,6 +822,12 @@ class FfxApiProxy
result = fg_dx12.DestroyContext(context, memCb);
break;
case FFXStructType::Denoiser:
LOG_DEBUG("Destroying with denoiser_dx12");
if (denoiser_dx12.dll != nullptr)
result = denoiser_dx12.DestroyContext(context, memCb);
break;
default:
break;
}
@@ -762,22 +887,26 @@ class FfxApiProxy
if (isFg && fg_dx12.dll != nullptr)
return fg_dx12.Configure(context, desc);
else if (!isFg && upscaling_dx12.dll != nullptr)
else if (type == FFXStructType::Upscaling && upscaling_dx12.dll != nullptr)
return upscaling_dx12.Configure(context, desc);
else if (type == FFXStructType::Denoiser && denoiser_dx12.dll != nullptr)
return denoiser_dx12.Configure(context, desc);
if (main_dx12.dll != nullptr && !(isFg && fg_dx12.skipConfigureCalls) &&
!(!isFg && upscaling_dx12.skipConfigureCalls))
const auto skipFG = isFg && fg_dx12.skipQueryCalls;
const auto skipUpscaling = type == FFXStructType::Upscaling && upscaling_dx12.skipQueryCalls;
if (main_dx12.dll != nullptr && !skipFG && !skipUpscaling)
{
if (isFg)
fg_dx12.skipConfigureCalls = true;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipConfigureCalls = true;
auto result = main_dx12.Configure(context, desc);
if (isFg)
fg_dx12.skipConfigureCalls = false;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipConfigureCalls = false;
return result;
@@ -793,21 +922,26 @@ class FfxApiProxy
if (isFg && fg_dx12.dll != nullptr)
return fg_dx12.Query(context, desc);
else if (!isFg && upscaling_dx12.dll != nullptr)
else if (type == FFXStructType::Upscaling && upscaling_dx12.dll != nullptr)
return upscaling_dx12.Query(context, desc);
else if (type == FFXStructType::Denoiser && denoiser_dx12.dll != nullptr)
return denoiser_dx12.Query(context, desc);
if (main_dx12.dll != nullptr && !(isFg && fg_dx12.skipQueryCalls) && !(!isFg && upscaling_dx12.skipQueryCalls))
const auto skipFG = isFg && fg_dx12.skipQueryCalls;
const auto skipUpscaling = type == FFXStructType::Upscaling && upscaling_dx12.skipQueryCalls;
if (main_dx12.dll != nullptr && !skipFG && !skipUpscaling)
{
if (isFg)
fg_dx12.skipQueryCalls = true;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipQueryCalls = true;
auto result = main_dx12.Query(context, desc);
if (isFg)
fg_dx12.skipQueryCalls = false;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipQueryCalls = false;
return result;
@@ -823,22 +957,26 @@ class FfxApiProxy
if (isFg && fg_dx12.dll != nullptr)
return fg_dx12.Dispatch(context, desc);
else if (!isFg && upscaling_dx12.dll != nullptr)
else if (type == FFXStructType::Upscaling && upscaling_dx12.dll != nullptr)
return upscaling_dx12.Dispatch(context, desc);
else if (type == FFXStructType::Denoiser && denoiser_dx12.dll != nullptr)
return denoiser_dx12.Dispatch(context, desc);
if (main_dx12.dll != nullptr && !(isFg && fg_dx12.skipDispatchCalls) &&
!(!isFg && upscaling_dx12.skipDispatchCalls))
const auto skipFG = isFg && fg_dx12.skipQueryCalls;
const auto skipUpscaling = type == FFXStructType::Upscaling && upscaling_dx12.skipQueryCalls;
if (main_dx12.dll != nullptr && !skipFG && !skipUpscaling)
{
if (isFg)
fg_dx12.skipDispatchCalls = true;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipDispatchCalls = true;
auto result = main_dx12.Dispatch(context, desc);
if (isFg)
fg_dx12.skipDispatchCalls = false;
else
else if (type == FFXStructType::Upscaling)
upscaling_dx12.skipDispatchCalls = false;
return result;