From e0f97ea00651ffb894808549249eaf83518adcc9 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Wed, 12 Mar 2025 16:18:27 +0100 Subject: [PATCH] Explicitly load the correct FFX API DLL based on the active graphics backend, and use functions dynamically loaded from that library. This allows both DX12 and Vulkan to work properly from the same codebase. --- FSR3UnityPlugin.cpp | 44 ++++++++++++++++++++++++++++++++++------- FSR3UnityPlugin.vcxproj | 4 ++-- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/FSR3UnityPlugin.cpp b/FSR3UnityPlugin.cpp index 1a71137..a3bbc3b 100644 --- a/FSR3UnityPlugin.cpp +++ b/FSR3UnityPlugin.cpp @@ -14,6 +14,7 @@ #include "UnityPluginAPI/IUnityGraphicsD3D12.h" #include "UnityPluginAPI/IUnityGraphicsVulkan.h" +#include "ffx_api/ffx_api_loader.h" #include "ffx_api/ffx_upscale.hpp" #include "ffx_api/dx12/ffx_api_dx12.hpp" #include "ffx_api/vk/ffx_api_vk.hpp" @@ -48,6 +49,8 @@ static std::vector s_Features; static std::queue s_FeatureSlots; static std::mutex s_FeatureMutex; +static HMODULE s_ffxModule = nullptr; +static ffxFunctions s_ffxFunctions{}; static ffx::CreateBackendDX12Desc s_DX12BackendDesc{}; static ffx::CreateBackendVKDesc s_VulkanBackendDesc{}; @@ -156,6 +159,25 @@ static PFN_vkVoidFunction GetVulkanDeviceProcAddr(VkDevice device, const char* p return instance.getInstanceProcAddr(instance.instance, pName); } +static bool LoadFidelityFXLibrary(_In_ LPCWSTR lpLibFileName) +{ + s_ffxModule = LoadLibrary(lpLibFileName); + if (s_ffxModule == nullptr) + { + UNITY_LOG_ERROR(s_Log, "Failed to load FidelityFX library!"); + return false; + } + + ffxLoadFunctions(&s_ffxFunctions, s_ffxModule); + if (s_ffxFunctions.CreateContext == nullptr) + { + UNITY_LOG_ERROR(s_Log, "Failed to load FidelityFX library functions!"); + return false; + } + + return true; +} + extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() { if (s_GraphicsD3D12 != nullptr) @@ -165,7 +187,8 @@ extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() return false; s_DX12BackendDesc.device = device; - return true; + + return LoadFidelityFXLibrary(TEXT("amd_fidelityfx_dx12.dll")); } else if (s_GraphicsVulkan != nullptr) { @@ -176,7 +199,8 @@ extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() s_VulkanBackendDesc.vkDevice = instance.device; s_VulkanBackendDesc.vkPhysicalDevice = instance.physicalDevice; s_VulkanBackendDesc.vkDeviceProcAddr = &GetVulkanDeviceProcAddr; - return true; + + return LoadFidelityFXLibrary(TEXT("amd_fidelityfx_vk.dll")); } return false; @@ -189,10 +213,16 @@ extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_ShutdownApi() auto& feature = s_Features[slot]; if (feature.upscalingContext != nullptr) { - ffx::DestroyContext(feature.upscalingContext); + s_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); FreeFeatureSlot(slot); } } + + if (s_ffxModule != nullptr) + { + FreeLibrary(s_ffxModule); + s_ffxModule = nullptr; + } s_VulkanBackendDesc.vkDevice = nullptr; s_VulkanBackendDesc.vkPhysicalDevice = nullptr; @@ -288,7 +318,7 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) auto& feature = s_Features[featureSlot]; if (feature.upscalingContext != nullptr) { - ffx::DestroyContext(feature.upscalingContext); + s_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); FreeFeatureSlot(featureSlot); } break; @@ -359,7 +389,7 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) dispatchUpscale.cameraNear = params->cameraNear; } - ffx::Dispatch(feature.upscalingContext, dispatchUpscale); + s_ffxFunctions.Dispatch(&feature.upscalingContext, &dispatchUpscale.header); break; } case BaseEventId + FSR3PluginEvent::ePostExecute: @@ -385,11 +415,11 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) if (s_GraphicsD3D12 != nullptr) { - ffx::CreateContext(feature.upscalingContext, nullptr, createUpscaling, s_DX12BackendDesc); + s_ffxFunctions.CreateContext(&feature.upscalingContext, ffx::LinkHeaders(createUpscaling.header, s_DX12BackendDesc.header), nullptr); } else if (s_GraphicsVulkan != nullptr) { - ffx::CreateContext(feature.upscalingContext, nullptr, createUpscaling, s_VulkanBackendDesc); + s_ffxFunctions.CreateContext(&feature.upscalingContext, ffx::LinkHeaders(createUpscaling.header, s_VulkanBackendDesc.header), nullptr); } break; } diff --git a/FSR3UnityPlugin.vcxproj b/FSR3UnityPlugin.vcxproj index 261d6d6..72d22c9 100644 --- a/FSR3UnityPlugin.vcxproj +++ b/FSR3UnityPlugin.vcxproj @@ -124,7 +124,7 @@ Windows true false - $(CoreLibraryDependencies);%(AdditionalDependencies);lib\amd_fidelityfx_dx12.lib;lib\amd_fidelityfx_vk.lib;vulkan-1.lib + $(CoreLibraryDependencies);%(AdditionalDependencies);vulkan-1.lib %VULKAN_SDK%\Lib;%(AdditionalLibraryDirectories) @@ -146,7 +146,7 @@ true true false - $(CoreLibraryDependencies);%(AdditionalDependencies);lib\amd_fidelityfx_dx12.lib;lib\amd_fidelityfx_vk.lib;vulkan-1.lib + $(CoreLibraryDependencies);%(AdditionalDependencies);vulkan-1.lib %VULKAN_SDK%\Lib;%(AdditionalLibraryDirectories)