Browse Source

Moved handling of FidelityFX library and dynamic function loading into a separate base class, and reworked some things so that only UpscalerGraphicsDevice needs to access the mutex

master
Nico de Poel 10 months ago
parent
commit
8fc9a23c3a
  1. 1
      FSR3UnityPlugin.vcxproj
  2. 3
      FSR3UnityPlugin.vcxproj.filters
  3. 101
      FSR3Upscaler_DX12.cpp
  4. 31
      FSR3Upscaler_DX12.h
  5. 94
      FSR3Upscaler_FFXBase.h
  6. 9
      UpscalerGraphicsDevice.h

1
FSR3UnityPlugin.vcxproj

@ -157,6 +157,7 @@
<ItemGroup>
<ClInclude Include="FSR3UnityTypes.h" />
<ClInclude Include="FSR3Upscaler_DX12.h" />
<ClInclude Include="FSR3Upscaler_FFXBase.h" />
<ClInclude Include="UpscalerGraphicsDevice.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

3
FSR3UnityPlugin.vcxproj.filters

@ -32,5 +32,8 @@
<ClInclude Include="FSR3Upscaler_DX12.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FSR3Upscaler_FFXBase.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

101
FSR3Upscaler_DX12.cpp

@ -3,59 +3,6 @@
#include <d3d12.h>
#include <dxgi.h>
// TODO: find a better place to put this, including the UnityLog and FFX API Loader includes
#include <sstream>
#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<const char*> versionNames;
std::vector<uint64_t> 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<std::mutex> 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;
}

31
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<FSR3Feature_DX12>
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;

94
FSR3Upscaler_FFXBase.h

@ -0,0 +1,94 @@
#pragma once
#include "UpscalerGraphicsDevice.h"
#include <sstream>
#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<FSR3Feature_FFX>
{
public:
FSR3Upscaler_FFXBase(IUnityInterfaces* unityInterfaces)
: m_ffxModule(NULL)
{
m_Log = unityInterfaces->Get<IUnityLog>();
}
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<const char*> versionNames;
std::vector<uint64_t> 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;
};

9
UpscalerGraphicsDevice.h

@ -14,7 +14,7 @@ template<typename TFeature> 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<std::mutex> 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<TFeature> m_Features;
std::queue<uint32_t> m_FeatureSlots;
std::mutex m_Mutex;
};
Loading…
Cancel
Save