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;
};