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