Browse Source

Reimplemented upscaling using the older FSR2 API for DX12

fsr2
Nico de Poel 11 months ago
parent
commit
d822598778
  1. 130
      FSR3UnityPlugin.cpp
  2. 4
      FSR3UnityPlugin.vcxproj
  3. 5
      FSR3UnityTypes.h

130
FSR3UnityPlugin.cpp

@ -13,8 +13,8 @@
#include <dxgi.h> #include <dxgi.h>
#include "UnityPluginAPI/IUnityGraphicsD3D12.h" #include "UnityPluginAPI/IUnityGraphicsD3D12.h"
#include "ffx_api/ffx_upscale.hpp"
#include "ffx_api/dx12/ffx_api_dx12.hpp"
#include "ffx-fsr2-api/ffx_fsr2.h"
#include "ffx-fsr2-api/dx12/ffx_fsr2_dx12.h"
#include "FSR3UnityTypes.h" #include "FSR3UnityTypes.h"
@ -26,17 +26,18 @@ static IUnityGraphics* s_Graphics = nullptr;
static IUnityGraphicsD3D12v7* s_GraphicsD3D12 = nullptr; static IUnityGraphicsD3D12v7* s_GraphicsD3D12 = nullptr;
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull; static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;
static FfxDevice s_Device = nullptr;
static FfxFsr2Interface s_Fsr2Interface;
static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType); static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType);
static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data); static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data);
static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data); static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data);
struct FSR3Feature struct FSR3Feature
{ {
ffx::Context upscalingContext;
uint32_t upscaleSizeWidth;
uint32_t upscaleSizeHeight;
FfxFsr2Context upscalingContext;
uint32_t flags; uint32_t flags;
bool isValid;
FSR3TextureTable textureTable; FSR3TextureTable textureTable;
}; };
@ -45,8 +46,6 @@ static std::vector<FSR3Feature> s_Features;
static std::queue<uint32_t> s_FeatureSlots; static std::queue<uint32_t> s_FeatureSlots;
static std::mutex s_FeatureMutex; static std::mutex s_FeatureMutex;
static ffx::CreateBackendDX12Desc s_BackendDesc{};
// Unity plugin load event // Unity plugin load event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces) extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{ {
@ -103,7 +102,7 @@ static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType ev
}; };
} }
// Thread-safe allocation of FSR3 feature slot
// Thread-safe allocation of feature slot
static uint32_t AllocateFeatureSlot() static uint32_t AllocateFeatureSlot()
{ {
std::lock_guard<std::mutex> lock(s_FeatureMutex); std::lock_guard<std::mutex> lock(s_FeatureMutex);
@ -122,7 +121,7 @@ static uint32_t AllocateFeatureSlot()
return featureSlot; return featureSlot;
} }
// Thread-safe freeing and clearing of FSR3 feature slot
// Thread-safe freeing and clearing of feature slot
static void FreeFeatureSlot(uint32_t featureSlot) static void FreeFeatureSlot(uint32_t featureSlot)
{ {
std::lock_guard<std::mutex> lock(s_FeatureMutex); std::lock_guard<std::mutex> lock(s_FeatureMutex);
@ -140,7 +139,12 @@ extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi()
if (device == nullptr) if (device == nullptr)
return false; return false;
s_BackendDesc.device = device;
s_Device = ffxGetDeviceDX12(device);
size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeDX12();
void* scratchBuffer = malloc(scratchBufferSize);
ffxFsr2GetInterfaceDX12(&s_Fsr2Interface, device, scratchBuffer, scratchBufferSize);
return true; return true;
} }
@ -149,14 +153,20 @@ extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_ShutdownApi()
for (uint32_t slot = 0; slot < s_Features.size(); ++slot) for (uint32_t slot = 0; slot < s_Features.size(); ++slot)
{ {
auto& feature = s_Features[slot]; auto& feature = s_Features[slot];
if (feature.upscalingContext != nullptr)
if (feature.isValid)
{ {
ffx::DestroyContext(feature.upscalingContext);
ffxFsr2ContextDestroy(&feature.upscalingContext);
FreeFeatureSlot(slot); FreeFeatureSlot(slot);
} }
} }
s_BackendDesc.device = nullptr;
if (s_Fsr2Interface.scratchBuffer != nullptr)
{
free(s_Fsr2Interface.scratchBuffer);
s_Fsr2Interface.scratchBuffer = nullptr;
}
s_Device = nullptr;
} }
extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetDeviceVersion() extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetDeviceVersion()
@ -215,7 +225,7 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetBaseEvent
// Plugin function to handle a specific rendering event // Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
{ {
if (s_GraphicsD3D12 == nullptr || s_BackendDesc.device == nullptr)
if (s_GraphicsD3D12 == nullptr || s_Device == nullptr)
return; return;
// User rendering code // User rendering code
@ -228,9 +238,9 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
return; return;
auto& feature = s_Features[featureSlot]; auto& feature = s_Features[featureSlot];
if (feature.upscalingContext != nullptr)
if (feature.isValid)
{ {
ffx::DestroyContext(feature.upscalingContext);
ffxFsr2ContextDestroy(&feature.upscalingContext);
FreeFeatureSlot(featureSlot); FreeFeatureSlot(featureSlot);
} }
break; break;
@ -243,47 +253,45 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
auto& feature = s_Features[params->featureSlot]; auto& feature = s_Features[params->featureSlot];
FfxFsr2DispatchDescription dispatchDescription{};
UnityGraphicsD3D12RecordingState state; UnityGraphicsD3D12RecordingState state;
s_GraphicsD3D12->CommandRecordingState(&state); s_GraphicsD3D12->CommandRecordingState(&state);
ffx::DispatchDescUpscale dispatchUpscale{};
dispatchUpscale.commandList = state.commandList;
dispatchUpscale.color = ffxApiGetResourceDX12((ID3D12Resource*)feature.textureTable.colorInput, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
dispatchUpscale.depth = ffxApiGetResourceDX12((ID3D12Resource*)feature.textureTable.depth, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
dispatchUpscale.motionVectors = ffxApiGetResourceDX12((ID3D12Resource*)feature.textureTable.motionVectors, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
dispatchUpscale.exposure = ffxApiGetResourceDX12((ID3D12Resource*)feature.textureTable.exposureTexture, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
dispatchUpscale.reactive = ffxApiGetResourceDX12((ID3D12Resource*)feature.textureTable.reactiveMask, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
dispatchUpscale.transparencyAndComposition = ffxApiGetResourceDX12((ID3D12Resource*)feature.textureTable.transparencyMask, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
dispatchUpscale.output = ffxApiGetResourceDX12((ID3D12Resource*)feature.textureTable.colorOutput, FFX_API_RESOURCE_STATE_UNORDERED_ACCESS);
dispatchUpscale.jitterOffset.x = params->jitterOffsetX;
dispatchUpscale.jitterOffset.y = params->jitterOffsetY;
dispatchUpscale.motionVectorScale.x = params->MVScaleX;
dispatchUpscale.motionVectorScale.y = params->MVScaleY;
dispatchUpscale.reset = params->reset;
dispatchUpscale.enableSharpening = params->enableSharpening;
dispatchUpscale.sharpness = params->sharpness;
dispatchUpscale.frameTimeDelta = params->frameTimeDelta;
dispatchUpscale.preExposure = params->preExposure;
dispatchUpscale.renderSize.width = params->renderSizeWidth;
dispatchUpscale.renderSize.height = params->renderSizeHeight;
dispatchUpscale.upscaleSize.width = feature.upscaleSizeWidth;
dispatchUpscale.upscaleSize.height = feature.upscaleSizeHeight;
dispatchUpscale.cameraFovAngleVertical = params->cameraFovAngleVertical;
if (feature.flags & FFX_UPSCALE_ENABLE_DEPTH_INVERTED)
dispatchDescription.commandList = ffxGetCommandListDX12(state.commandList);
dispatchDescription.color = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.colorInput);
dispatchDescription.depth = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.depth);
dispatchDescription.motionVectors = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.motionVectors);
dispatchDescription.exposure = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.exposureTexture);
dispatchDescription.reactive = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.reactiveMask);
dispatchDescription.transparencyAndComposition = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.transparencyMask);
dispatchDescription.output = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.colorOutput, nullptr, FFX_RESOURCE_STATE_UNORDERED_ACCESS);
dispatchDescription.jitterOffset.x = params->jitterOffsetX;
dispatchDescription.jitterOffset.y = params->jitterOffsetY;
dispatchDescription.motionVectorScale.x = params->MVScaleX;
dispatchDescription.motionVectorScale.y = params->MVScaleY;
dispatchDescription.reset = params->reset;
dispatchDescription.enableSharpening = params->enableSharpening;
dispatchDescription.sharpness = params->sharpness;
dispatchDescription.frameTimeDelta = params->frameTimeDelta;
dispatchDescription.preExposure = params->preExposure;
dispatchDescription.renderSize.width = params->renderSizeWidth;
dispatchDescription.renderSize.height = params->renderSizeHeight;
dispatchDescription.cameraFovAngleVertical = params->cameraFovAngleVertical;
if (feature.flags & FFX_FSR2_ENABLE_DEPTH_INVERTED)
{ {
dispatchUpscale.cameraFar = params->cameraNear;
dispatchUpscale.cameraNear = params->cameraFar;
dispatchDescription.cameraFar = params->cameraNear;
dispatchDescription.cameraNear = params->cameraFar;
} }
else else
{ {
dispatchUpscale.cameraFar = params->cameraFar;
dispatchUpscale.cameraNear = params->cameraNear;
dispatchDescription.cameraFar = params->cameraFar;
dispatchDescription.cameraNear = params->cameraNear;
} }
ffx::Dispatch(feature.upscalingContext, dispatchUpscale);
ffxFsr2ContextDispatch(&feature.upscalingContext, &dispatchDescription);
break; break;
} }
case BaseEventId + FSR3PluginEvent::ePostExecute: case BaseEventId + FSR3PluginEvent::ePostExecute:
@ -298,26 +306,18 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
return; return;
auto& feature = s_Features[params->featureSlot]; auto& feature = s_Features[params->featureSlot];
feature.upscaleSizeWidth = params->displaySizeWidth;
feature.upscaleSizeHeight = params->displaySizeHeight;
feature.flags = params->flags; feature.flags = params->flags;
ffx::CreateContextDescUpscale createUpscaling;
createUpscaling.maxUpscaleSize = { params->displaySizeWidth, params->displaySizeHeight };
createUpscaling.maxRenderSize = { params->maxRenderSizeWidth, params->maxRenderSizeHeight };
createUpscaling.flags = params->flags;
FfxFsr2ContextDescription contextDescription{};
contextDescription.callbacks = s_Fsr2Interface;
contextDescription.device = s_Device;
contextDescription.displaySize = { params->displaySizeWidth, params->displaySizeHeight };
contextDescription.maxRenderSize = { params->maxRenderSizeWidth, params->maxRenderSizeHeight };
contextDescription.flags = params->flags;
ffx::CreateContext(feature.upscalingContext, nullptr, createUpscaling, s_BackendDesc);
feature.isValid = ffxFsr2ContextCreate(&feature.upscalingContext, &contextDescription) == FFX_OK;
break; break;
} }
case BaseEventId + FSR3PluginEvent::eSetTextures:
auto* params = (FSR3TextureTable*)data;
if (params->featureSlot < 0 || params->featureSlot >= s_Features.size())
return;
auto& feature = s_Features[params->featureSlot];
feature.textureTable = *params;
break;
} }
} }

4
FSR3UnityPlugin.vcxproj

@ -123,7 +123,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);lib\amd_fidelityfx_dx12.lib</AdditionalDependencies>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);lib\ffx_fsr2_api\ffx_fsr2_api_x64d.lib;lib\ffx_fsr2_api\ffx_fsr2_api_dx12_x64d.lib</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -143,7 +143,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);lib\amd_fidelityfx_dx12.lib</AdditionalDependencies>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);lib\ffx_fsr2_api\ffx_fsr2_api_x64.lib;lib\ffx_fsr2_api\ffx_fsr2_api_dx12_x64.lib</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

5
FSR3UnityTypes.h

@ -5,8 +5,7 @@ enum FSR3PluginEvent : int32_t
eDestroyFeature, eDestroyFeature,
eExecute, eExecute,
ePostExecute, ePostExecute,
eInit,
eSetTextures
eInit
}; };
enum FSR3Quality: int32_t enum FSR3Quality: int32_t
@ -70,6 +69,4 @@ struct FSR3TextureTable
intptr_t exposureTexture; intptr_t exposureTexture;
intptr_t reactiveMask; intptr_t reactiveMask;
intptr_t biasColorMask; intptr_t biasColorMask;
uint32_t featureSlot;
}; };
Loading…
Cancel
Save