@ -33,6 +33,11 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data);
struct FSR3Feature
struct FSR3Feature
{
{
ffx : : Context upscalingContext ;
ffx : : Context upscalingContext ;
uint32_t upscaleSizeWidth ;
uint32_t upscaleSizeHeight ;
uint32_t flags ;
FSR3TextureTable textureTable ;
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 ( )
extern " C " void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_ShutdownApi ( )
{
{
// TODO: destroy any remaining FSR3Context s?
// TODO: destroy any remaining FSR3Feature s?
s_BackendDesc . device = nullptr ;
s_BackendDesc . device = nullptr ;
}
}
@ -163,16 +168,32 @@ extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_CreateFeatu
return AllocateFeatureSlot ( ) ;
return AllocateFeatureSlot ( ) ;
}
}
extern " C " bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetRenderResolution FromQualityMode ( FSR3Quality qualityMode , uint32_t displayWidth , uint32_t displayHeight , uint32_t * renderWidth , uint32_t * renderHeight )
extern " C " float UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetUpscaleRatio FromQualityMode ( 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_GetRenderResolution FromQualityMode ( 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 ( )
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
// 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 )
return ;
// User rendering code
// User rendering code
switch ( eventID )
switch ( eventID )
{
{
case BaseEventId + FSR3PluginEvent : : eDestroyFeature :
case BaseEventId + FSR3PluginEvent : : eDestroyFeature :
{
{
uint32_t featureSlot = ( uint32_t ) ( int64_t ) data ;
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 ) ;
FreeFeatureSlot ( featureSlot ) ;
break ;
break ;
}
}
case BaseEventId + FSR3PluginEvent : : eExecute :
case BaseEventId + FSR3PluginEvent : : eExecute :
{
{
auto * params = ( FSR3CommandExecutionData * ) data ;
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 ;
break ;
}
}
case BaseEventId + FSR3PluginEvent : : ePostExecute :
case BaseEventId + FSR3PluginEvent : : ePostExecute :
@ -205,14 +281,14 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
}
}
case BaseEventId + FSR3PluginEvent : : eInit :
case BaseEventId + FSR3PluginEvent : : eInit :
{
{
if ( s_BackendDesc . device = = nullptr )
return ;
auto * params = ( FSR3CommandInitializationData * ) data ;
auto * params = ( FSR3CommandInitializationData * ) data ;
if ( params - > featureSlot < 0 | | params - > featureSlot > = s_Features . size ( ) )
if ( params - > featureSlot < 0 | | params - > featureSlot > = s_Features . size ( ) )
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 ;
ffx : : CreateContextDescUpscale createUpscaling ;
ffx : : CreateContextDescUpscale createUpscaling ;
createUpscaling . maxUpscaleSize = { params - > displaySizeWidth , params - > displaySizeHeight } ;
createUpscaling . maxUpscaleSize = { params - > displaySizeWidth , params - > displaySizeHeight } ;
@ -230,16 +306,26 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data)
auto * params = ( UnityRenderingExtTextureUpdateParamsV2 * ) data ;
auto * params = ( UnityRenderingExtTextureUpdateParamsV2 * ) data ;
uint32_t featureSlot = ( params - > userData > > 16 ) & 0xFFFF ;
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 ;
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
// User rendering code
switch ( eventID )
switch ( eventID )
{
{
case kUnityRenderingExtEventUpdateTextureBeginV2 :
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 ;
break ;
}
}
case kUnityRenderingExtEventUpdateTextureEndV2 :
case kUnityRenderingExtEventUpdateTextureEndV2 :