diff --git a/FSR3UnityPlugin.vcxproj b/FSR3UnityPlugin.vcxproj index 522b818..9227741 100644 --- a/FSR3UnityPlugin.vcxproj +++ b/FSR3UnityPlugin.vcxproj @@ -157,6 +157,7 @@ + diff --git a/FSR3UnityPlugin.vcxproj.filters b/FSR3UnityPlugin.vcxproj.filters index 3e2551b..5f054da 100644 --- a/FSR3UnityPlugin.vcxproj.filters +++ b/FSR3UnityPlugin.vcxproj.filters @@ -32,5 +32,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/FSR3Upscaler_DX12.cpp b/FSR3Upscaler_DX12.cpp index d4e2c5b..6dfd6d8 100644 --- a/FSR3Upscaler_DX12.cpp +++ b/FSR3Upscaler_DX12.cpp @@ -3,59 +3,6 @@ #include #include -// TODO: find a better place to put this, including the UnityLog and FFX API Loader includes -#include -#include "ffx_api/ffx_api_loader.h" -#include "UnityPluginAPI/IUnityLog.h" -static IUnityLog* s_Log = nullptr; -static HMODULE s_ffxModule = nullptr; -static ffxFunctions s_ffxFunctions{}; -static bool LoadFidelityFXLibrary(_In_ LPCWSTR lpLibFileName, void* device) -{ - 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; - } - - // Check that we can actually create an upscaler with this library - ffx::QueryDescGetVersions versionQuery{}; - versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE; - versionQuery.device = device; - uint64_t versionCount = 0; - versionQuery.outputCount = &versionCount; - s_ffxFunctions.Query(nullptr, &versionQuery.header); - - if (versionCount == 0) - { - UNITY_LOG_ERROR(s_Log, "Failed to load FidelityFX upscaler versions!"); - return false; - } - - // Obtain the default upscaler version and log its name - std::vector versionNames; - std::vector versionIds; - versionIds.resize(versionCount); - versionNames.resize(versionCount); - versionQuery.versionIds = versionIds.data(); - versionQuery.versionNames = versionNames.data(); - s_ffxFunctions.Query(nullptr, &versionQuery.header); - - std::stringstream ss; - ss << "Loaded FidelityFX upscaler: FSR " << versionNames[0]; - UNITY_LOG(s_Log, ss.str().c_str()); - - return true; -} - bool FSR3Upscaler_DX12::Init() { ID3D12Device* device = m_GraphicsDevice->GetDevice(); @@ -68,35 +15,14 @@ bool FSR3Upscaler_DX12::Init() return LoadFidelityFXLibrary(TEXT("amd_fidelityfx_dx12.dll"), device); } -void FSR3Upscaler_DX12::Shutdown() -{ - UpscalerGraphicsDevice::Shutdown(); // TODO: change to FSR3Upscaler_FFXBase::Shutdown - - std::lock_guard lock(m_Mutex); // TODO: see if we can rearrange this to only require mutexes in UpscalerGraphicsDevice - - if (s_ffxModule != nullptr) // TODO: move to base FSR3Upscaler_FFXBase class - { - FreeLibrary(s_ffxModule); - s_ffxModule = nullptr; - } - - if (m_FrameFenceEventHandle != nullptr) - { - CloseHandle(m_FrameFenceEventHandle); - m_FrameFenceEventHandle = nullptr; - } - - m_DX12BackendDesc.device = nullptr; -} - -bool FSR3Upscaler_DX12::InitFeature(FSR3Feature_DX12& feature, const FSR3CommandInitializationData* initData) +bool FSR3Upscaler_DX12::InitFeature(FSR3Feature_FFX& feature, const FSR3CommandInitializationData* initData) { ffx::CreateContextDescUpscale createUpscaling; createUpscaling.maxUpscaleSize = { initData->displaySizeWidth, initData->displaySizeHeight }; createUpscaling.maxRenderSize = { initData->maxRenderSizeWidth, initData->maxRenderSizeHeight }; createUpscaling.flags = initData->flags; - return FFX_API_RETURN_OK == s_ffxFunctions.CreateContext(&feature.upscalingContext, ffx::LinkHeaders(createUpscaling.header, m_DX12BackendDesc.header), nullptr); + return FFX_API_RETURN_OK == m_ffxFunctions.CreateContext(&feature.upscalingContext, ffx::LinkHeaders(createUpscaling.header, m_DX12BackendDesc.header), nullptr); } void FSR3Upscaler_DX12::SetTexture(FSR3TextureDesc* textureDesc, UnityTextureID textureID) @@ -104,7 +30,7 @@ void FSR3Upscaler_DX12::SetTexture(FSR3TextureDesc* textureDesc, UnityTextureID textureDesc->image = (intptr_t)m_GraphicsDevice->TextureFromNativeTexture(textureID); } -void FSR3Upscaler_DX12::Execute(FSR3Feature_DX12& feature, const FSR3CommandExecutionData* execData) +void FSR3Upscaler_DX12::Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData) { ffx::DispatchDescUpscale dispatchUpscale{}; @@ -152,10 +78,10 @@ void FSR3Upscaler_DX12::Execute(FSR3Feature_DX12& feature, const FSR3CommandExec dispatchUpscale.cameraNear = execData->cameraNear; } - s_ffxFunctions.Dispatch(&feature.upscalingContext, &dispatchUpscale.header); + m_ffxFunctions.Dispatch(&feature.upscalingContext, &dispatchUpscale.header); } -bool FSR3Upscaler_DX12::IsValidFeature(FSR3Feature_DX12& feature) +bool FSR3Upscaler_DX12::IsValidFeature(FSR3Feature_FFX& feature) { return feature.upscalingContext != nullptr; } @@ -171,7 +97,20 @@ void FSR3Upscaler_DX12::AwaitEndOfFrame(uint64_t frameValue) } } -void FSR3Upscaler_DX12::DestroyContext(FSR3Feature_DX12& feature) +void FSR3Upscaler_DX12::DestroyContext(FSR3Feature_FFX& feature) { - s_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); + m_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); +} + +void FSR3Upscaler_DX12::DoShutdown() +{ + FSR3Upscaler_FFXBase::DoShutdown(); + + if (m_FrameFenceEventHandle != nullptr) + { + CloseHandle(m_FrameFenceEventHandle); + m_FrameFenceEventHandle = nullptr; + } + + m_DX12BackendDesc.device = nullptr; } diff --git a/FSR3Upscaler_DX12.h b/FSR3Upscaler_DX12.h index 68447c8..e82cdc7 100644 --- a/FSR3Upscaler_DX12.h +++ b/FSR3Upscaler_DX12.h @@ -1,44 +1,33 @@ #pragma once -#include "UpscalerGraphicsDevice.h" +#include "FSR3Upscaler_FFXBase.h" #include "ffx_api/ffx_upscale.hpp" #include "ffx_api/dx12/ffx_api_dx12.hpp" #include "UnityPluginAPI/IUnityGraphicsD3D12.h" -struct FSR3Feature_DX12 -{ - ffx::Context upscalingContext; - - uint32_t upscaleSizeWidth; - uint32_t upscaleSizeHeight; - uint32_t flags; - - uint64_t dispatchFrameValue; - - FSR3TextureTable textureTable; -}; - -class FSR3Upscaler_DX12 : UpscalerGraphicsDevice +class FSR3Upscaler_DX12 : FSR3Upscaler_FFXBase { public: - FSR3Upscaler_DX12(IUnityGraphicsD3D12v7* graphicsDevice): + FSR3Upscaler_DX12(IUnityInterfaces* unityInterfaces, IUnityGraphicsD3D12v7* graphicsDevice): + FSR3Upscaler_FFXBase(unityInterfaces), m_GraphicsDevice(graphicsDevice), m_DX12BackendDesc(), m_FrameFenceEventHandle(nullptr) { } bool Init() override; - void Shutdown() override; protected: - bool IsValidFeature(FSR3Feature_DX12& feature) override; + bool IsValidFeature(FSR3Feature_FFX& feature) override; - bool InitFeature(FSR3Feature_DX12& feature, const FSR3CommandInitializationData* initData) override; + bool InitFeature(FSR3Feature_FFX& feature, const FSR3CommandInitializationData* initData) override; void SetTexture(FSR3TextureDesc* textureDesc, UnityTextureID textureID) override; - void Execute(FSR3Feature_DX12& feature, const FSR3CommandExecutionData* execData) override; + void Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData) override; void AwaitEndOfFrame(uint64_t frameValue) override; - void DestroyContext(FSR3Feature_DX12& feature) override; + void DestroyContext(FSR3Feature_FFX& feature) override; + + void DoShutdown() override; private: IUnityGraphicsD3D12v7* m_GraphicsDevice; diff --git a/FSR3Upscaler_FFXBase.h b/FSR3Upscaler_FFXBase.h new file mode 100644 index 0000000..5666306 --- /dev/null +++ b/FSR3Upscaler_FFXBase.h @@ -0,0 +1,94 @@ +#pragma once +#include "UpscalerGraphicsDevice.h" + +#include + +#include "UnityPluginAPI/IUnityLog.h" + +#include "ffx_api/ffx_upscale.hpp" +#include "ffx_api/ffx_api_loader.h" + +struct FSR3Feature_FFX +{ + ffx::Context upscalingContext; + + uint32_t upscaleSizeWidth; + uint32_t upscaleSizeHeight; + uint32_t flags; + + uint64_t dispatchFrameValue; + + FSR3TextureTable textureTable; +}; + +class FSR3Upscaler_FFXBase : UpscalerGraphicsDevice +{ +public: + FSR3Upscaler_FFXBase(IUnityInterfaces* unityInterfaces) + : m_ffxModule(NULL) + { + m_Log = unityInterfaces->Get(); + } + +protected: + bool LoadFidelityFXLibrary(_In_ LPCWSTR lpLibFileName, void* device) + { + m_ffxModule = LoadLibrary(lpLibFileName); + if (m_ffxModule == NULL) + { + UNITY_LOG_ERROR(m_Log, "Failed to load FidelityFX library!"); + return false; + } + + ffxLoadFunctions(&m_ffxFunctions, m_ffxModule); + if (m_ffxFunctions.CreateContext == nullptr) + { + UNITY_LOG_ERROR(m_Log, "Failed to load FidelityFX library functions!"); + return false; + } + + // Check that we can actually create an upscaler with this library + ffx::QueryDescGetVersions versionQuery{}; + versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE; + versionQuery.device = device; + uint64_t versionCount = 0; + versionQuery.outputCount = &versionCount; + m_ffxFunctions.Query(nullptr, &versionQuery.header); + + if (versionCount == 0) + { + UNITY_LOG_ERROR(m_Log, "Failed to load FidelityFX upscaler versions!"); + return false; + } + + // Obtain the default upscaler version and log its name + std::vector versionNames; + std::vector versionIds; + versionIds.resize(versionCount); + versionNames.resize(versionCount); + versionQuery.versionIds = versionIds.data(); + versionQuery.versionNames = versionNames.data(); + m_ffxFunctions.Query(nullptr, &versionQuery.header); + + std::stringstream ss; + ss << "Loaded FidelityFX upscaler: FSR " << versionNames[0]; + UNITY_LOG(m_Log, ss.str().c_str()); + + return true; + } + + void DoShutdown() override + { + if (m_ffxModule != nullptr) + { + FreeLibrary(m_ffxModule); + m_ffxModule = nullptr; + } + } + + ffxFunctions m_ffxFunctions{}; + +private: + IUnityLog* m_Log; + HMODULE m_ffxModule; +}; diff --git a/UpscalerGraphicsDevice.h b/UpscalerGraphicsDevice.h index e1250ef..e737d14 100644 --- a/UpscalerGraphicsDevice.h +++ b/UpscalerGraphicsDevice.h @@ -14,7 +14,7 @@ template class UpscalerGraphicsDevice public: virtual bool Init() = 0; // Called by AMDUP_InitAPI, does FidelityFX library loading - virtual void Shutdown() + void Shutdown() { // Called by AMDUP_ShutdownAPI, destroys all features, cleans up internal resources size_t numFeatures = 0; @@ -27,6 +27,10 @@ public: { DestroyFeature(slot); } + + std::lock_guard lock(m_Mutex); + + DoShutdown(); } uint32_t CreateFeatureSlot() @@ -135,7 +139,7 @@ protected: virtual void AwaitEndOfFrame(uint64_t frameValue) = 0; virtual void DestroyContext(TFeature& feature) = 0; - std::mutex m_Mutex; + virtual void DoShutdown() = 0; private: uint32_t AllocateFeatureSlot() @@ -168,4 +172,5 @@ private: std::vector m_Features; std::queue m_FeatureSlots; + std::mutex m_Mutex; };