Browse Source

Implemented what should be the rest of the FSR3 feature set. Still untested.

fsr2
Nico de Poel 11 months ago
parent
commit
cfcf81e50e
  1. 112
      FSR3UnityPlugin.cpp

112
FSR3UnityPlugin.cpp

@ -33,6 +33,11 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data);
struct FSR3Feature
{
ffx::Context upscalingContext;
uint32_t upscaleSizeWidth;
uint32_t upscaleSizeHeight;
uint32_t flags;
FSR3TextureTable textureTable;
};
@ -139,7 +144,7 @@ extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi()
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_ShutdownApi()
{
// TODO: destroy any remaining FSR3Contexts?
// TODO: destroy any remaining FSR3Features?
s_BackendDesc.device = nullptr;
}
@ -163,16 +168,32 @@ extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_CreateFeatu
return AllocateFeatureSlot();
}
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetRenderResolutionFromQualityMode(FSR3Quality qualityMode, uint32_t displayWidth, uint32_t displayHeight, uint32_t* renderWidth, uint32_t* renderHeight)
extern "C" float UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetUpscaleRatioFromQualityMode(FSR3Quality qualityMode)
{
// TODO: implement
return false;
switch (qualityMode)
{
case FSR3Quality::qQuality:
return 1.5f;
case FSR3Quality::qBalanced:
return 1.7f;
case FSR3Quality::qPerformance:
return 2.0f;
case FSR3Quality::qUltraPerformance:
return 3.0f;
default:
return 1.0f;
}
}
extern "C" float UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetUpscaleRatioFromQualityMode(FSR3Quality qualityMode)
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetRenderResolutionFromQualityMode(FSR3Quality qualityMode, uint32_t displayWidth, uint32_t displayHeight, uint32_t* renderWidth, uint32_t* renderHeight)
{
// TODO: implement
return 1.0f;
if (renderWidth == nullptr || renderHeight == nullptr)
return false;
float ratio = AMDUP_GetUpscaleRatioFromQualityMode(qualityMode);
*renderWidth = (uint32_t)roundf(displayWidth / ratio);
*renderHeight = (uint32_t)roundf(displayHeight / ratio);
return true;
}
extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetBaseEventId()
@ -183,19 +204,74 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetBaseEvent
// Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
{
if (s_GraphicsD3D12 == nullptr || s_BackendDesc.device == nullptr)
return;
// User rendering code
switch (eventID)
{
case BaseEventId + FSR3PluginEvent::eDestroyFeature:
{
uint32_t featureSlot = (uint32_t)(int64_t)data;
// TODO: destroy FSR3Context at feature slot index
if (featureSlot < 0 || featureSlot >= s_Features.size())
return;
auto& feature = s_Features[featureSlot];
ffx::DestroyContext(feature.upscalingContext);
FreeFeatureSlot(featureSlot);
break;
}
case BaseEventId + FSR3PluginEvent::eExecute:
{
auto* params = (FSR3CommandExecutionData*)data;
if (params->featureSlot < 0 || params->featureSlot >= s_Features.size())
return;
auto& feature = s_Features[params->featureSlot];
UnityGraphicsD3D12RecordingState 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.colorInput, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); // TODO: shouldn't this be FFX_API_RESOURCE_STATE_UNORDERED_ACCESS?
dispatchUpscale.jitterOffset.x = params->jitterOffsetX; // TODO: might need to negate these
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;
// TODO: it's possible that Unity already does this flip, check!
if (feature.flags & FFX_UPSCALE_ENABLE_DEPTH_INVERTED)
{
dispatchUpscale.cameraFar = params->cameraNear;
dispatchUpscale.cameraNear = params->cameraFar;
}
else
{
dispatchUpscale.cameraFar = params->cameraFar;
dispatchUpscale.cameraNear = params->cameraNear;
}
ffx::Dispatch(feature.upscalingContext, dispatchUpscale);
break;
}
case BaseEventId + FSR3PluginEvent::ePostExecute:
@ -205,14 +281,14 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
}
case BaseEventId + FSR3PluginEvent::eInit:
{
if (s_BackendDesc.device == nullptr)
return;
auto* params = (FSR3CommandInitializationData*)data;
if (params->featureSlot < 0 || params->featureSlot >= s_Features.size())
return;
auto& feature = s_Features[params->featureSlot];
feature.upscaleSizeWidth = params->displaySizeWidth;
feature.upscaleSizeHeight = params->displaySizeHeight;
feature.flags = params->flags;
ffx::CreateContextDescUpscale createUpscaling;
createUpscaling.maxUpscaleSize = { params->displaySizeWidth, params->displaySizeHeight };
@ -230,16 +306,26 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data)
auto* params = (UnityRenderingExtTextureUpdateParamsV2*)data;
uint32_t featureSlot = (params->userData >> 16) & 0xFFFF;
uint32_t textureSlot = (params->userData >> 1) & 0x7FFF; // TODO: could just use as numeric index to calculate a pointer offset
uint32_t textureSlot = (params->userData >> 1) & 0x7FFF;
uint32_t clearTextureTable = params->userData & 0x1;
// TODO: should be able to just cast params->textureID directly to a D3D12Resource*
if (featureSlot < 0 || featureSlot >= s_Features.size())
return;
auto& feature = s_Features[featureSlot];
if (clearTextureTable)
{
memset(&feature.textureTable, 0, sizeof(FSR3TextureTable));
}
// User rendering code
switch (eventID)
{
case kUnityRenderingExtEventUpdateTextureBeginV2:
{
// We organized the texture table struct to be ordered the same as the texture slot enum
// This way we can use the texture slot value simply as a pointer offset into the texture table
*(((intptr_t*)&feature.textureTable) + textureSlot) = params->textureID;
break;
}
case kUnityRenderingExtEventUpdateTextureEndV2:

Loading…
Cancel
Save