@ -1,4 +1,5 @@
using System.Runtime.InteropServices ;
using System ;
using System.Runtime.InteropServices ;
using UnityEngine ;
using UnityEngine.Assertions ;
using UnityEngine.Profiling ;
@ -192,8 +193,50 @@ namespace FidelityFX.FrameGen
bool executePreparationPasses = ( Constants . reset = = 0 ) ;
// TODO: do we have to clear some buffers somewhere on reset? Probably uninitialized RTs are kept to NULL in FFX source... we might want to clear them. Specifically the inputs for InterpolationPass.
// Schedule work for the interpolation command list
// TODO
_setupPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , renderDispatchSizeX , renderDispatchSizeY ) ;
Action dispatchGameVectorFieldInpaintingPyramid = ( ) = >
{
SetupSpdConstants ( dispatchDescription . renderSize , out var dispatchThreadGroupCount ) ;
commandBuffer . SetBufferData ( _spdConstantsBuffer , _spdConstantsArray ) ;
_gameVectorFieldInpaintingPyramidPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , dispatchThreadGroupCount . x , dispatchThreadGroupCount . y ) ;
} ;
// Only execute FG data preparation passes when reset wasn't triggered
if ( executePreparationPasses )
{
// Clear estimated depth resources
bool inverted = ( _contextDescription . flags & FrameInterpolation . InitializationFlags . EnableDepthInverted ) = = FrameInterpolation . InitializationFlags . EnableDepthInverted ;
commandBuffer . SetRenderTarget ( _resources . ReconstructedDepthInterpolatedFrame ) ;
commandBuffer . ClearRenderTarget ( false , true , inverted ? Color . clear : Color . white ) ;
_reconstructPreviousDepthPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , renderDispatchSizeX , renderDispatchSizeY ) ;
_gameMotionVectorFieldPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , renderDispatchSizeX , renderDispatchSizeY ) ;
dispatchGameVectorFieldInpaintingPyramid ( ) ;
_opticalFlowVectorFieldPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , opticalFlowDispatchSizeX , opticalFlowDispatchSizeY ) ;
_disocclusionMaskPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , renderDispatchSizeX , renderDispatchSizeY ) ;
}
_interpolationPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , displayDispatchSizeX , displayDispatchSizeY ) ;
// Inpainting pyramid
SetupSpdConstants ( dispatchDescription . displaySize , out var dispatchThreadGroupCount ) ;
commandBuffer . SetBufferData ( _spdConstantsBuffer , _spdConstantsArray ) ;
_inpaintingPyramidPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , dispatchThreadGroupCount . x , dispatchThreadGroupCount . y ) ;
_inpaintingPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , displayDispatchSizeX , displayDispatchSizeY ) ;
if ( ( dispatchDescription . flags & FrameInterpolation . DispatchFlags . DrawDebugView ) ! = 0 )
{
dispatchGameVectorFieldInpaintingPyramid ( ) ;
_debugViewPass . ScheduleDispatch ( commandBuffer , dispatchDescription , doubleBufferId , displayDispatchSizeX , displayDispatchSizeY ) ;
}
// Store current buffer
commandBuffer . CopyTexture ( FrameInterpolationShaderIDs . SrvCurrentInterpolationSource , _resources . PreviousInterpolationSource ) ;
commandBuffer . EndSample ( _sampler ) ;
}
@ -231,6 +274,37 @@ namespace FidelityFX.FrameGen
1.0f / cotHalfFovY ) ;
}
private void SetupSpdConstants ( Vector2Int resolution , out Vector2Int dispatchThreadGroupCount )
{
const int resolutionMultiplier = 1 ;
RectInt rectInfo = new RectInt ( 0 , 0 , resolution . x * resolutionMultiplier , resolution . y * resolutionMultiplier ) ;
SpdSetup ( rectInfo , out dispatchThreadGroupCount , out var workGroupOffset , out var numWorkGroupsAndMips , 4 ) ;
ref FrameInterpolation . InpaintingPyramidConstants spdConstants = ref SpdConstants ;
spdConstants . numWorkGroups = ( uint ) numWorkGroupsAndMips . x ;
spdConstants . mips = ( uint ) numWorkGroupsAndMips . y ;
spdConstants . workGroupOffsetX = ( uint ) workGroupOffset . x ;
spdConstants . workGroupOffsetY = ( uint ) workGroupOffset . y ;
}
private static void SpdSetup ( RectInt rectInfo , out Vector2Int dispatchThreadGroupCount , out Vector2Int workGroupOffset , out Vector2Int numWorkGroupsAndMips , int mips = - 1 )
{
workGroupOffset = new Vector2Int ( rectInfo . x / 6 4 , rectInfo . y / 6 4 ) ;
int endIndexX = ( rectInfo . x + rectInfo . width - 1 ) / 6 4 ;
int endIndexY = ( rectInfo . y + rectInfo . height - 1 ) / 6 4 ;
dispatchThreadGroupCount = new Vector2Int ( endIndexX + 1 - workGroupOffset . x , endIndexY + 1 - workGroupOffset . y ) ;
numWorkGroupsAndMips = new Vector2Int ( dispatchThreadGroupCount . x * dispatchThreadGroupCount . y , mips ) ;
if ( mips < 0 )
{
float resolution = Math . Max ( rectInfo . width , rectInfo . height ) ;
numWorkGroupsAndMips . y = Math . Min ( Mathf . FloorToInt ( Mathf . Log ( resolution , 2.0f ) ) , 1 2 ) ;
}
}
private int _debugIndex = 0 ;
private static readonly float [ ] DebugBarColorSequence =
{