using System; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.Profiling; using UnityEngine.Rendering; namespace FidelityFX.FrameGen { internal abstract class FrameInterpolationPass: IDisposable { protected readonly FrameInterpolation.ContextDescription ContextDescription; protected readonly FrameInterpolationResources Resources; protected readonly ComputeBuffer Constants; protected ComputeShader ComputeShader; protected int KernelIndex; protected CustomSampler Sampler; protected FrameInterpolationPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) { ContextDescription = contextDescription; Resources = resources; Constants = constants; } public virtual void Dispose() { } public void ScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ = 1) { commandBuffer.BeginSample(Sampler); DoScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchX, dispatchY, dispatchZ); commandBuffer.EndSample(Sampler); } protected abstract void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ); protected void InitComputeShader(string passName, ComputeShader shader) { InitComputeShader(passName, shader, ContextDescription.flags); } private void InitComputeShader(string passName, ComputeShader shader, FrameInterpolation.InitializationFlags flags) { if (shader == null) { throw new MissingReferenceException($"Shader for Frame Interpolation pass '{passName}' could not be loaded! Please ensure it is included in the project correctly."); } ComputeShader = shader; KernelIndex = ComputeShader.FindKernel("CS"); Sampler = CustomSampler.Create(passName); if ((flags & FrameInterpolation.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) ComputeShader.EnableKeyword("FFX_FRAMEINTERPOLATION_OPTION_LOW_RES_MOTION_VECTORS"); if ((flags & FrameInterpolation.InitializationFlags.EnableJitterMotionVectors) != 0) ComputeShader.EnableKeyword("FFX_FRAMEINTERPOLATION_OPTION_JITTERED_MOTION_VECTORS"); if ((flags & FrameInterpolation.InitializationFlags.EnableDepthInverted) != 0) ComputeShader.EnableKeyword("FFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH"); } protected void BindCurrentInterpolationSource(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams) { ref var backBuf = ref dispatchParams.currentBackBuffer; ref var bbNoHud = ref dispatchParams.currentBackBuffer_HUDLess; if (bbNoHud.IsValid) commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvCurrentInterpolationSource, bbNoHud.RenderTarget, bbNoHud.MipLevel, bbNoHud.SubElement); else commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvCurrentInterpolationSource, backBuf.RenderTarget, backBuf.MipLevel, backBuf.SubElement); } protected void BindMipmap(CommandBuffer commandBuffer, int nameID, RenderTexture renderTexture, int mipLevel) { mipLevel = Math.Min(mipLevel, renderTexture.mipmapCount - 1); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, nameID, renderTexture, mipLevel); } } internal class FrameInterpolationReconstructAndDilatePass : FrameInterpolationPass { public FrameInterpolationReconstructAndDilatePass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Reconstruct and Dilate", contextDescription.shaders.reconstructAndDilate); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { } public void ScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.PrepareDescription prepareParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ = 1) { commandBuffer.BeginSample(Sampler); ref var mvs = ref prepareParams.motionVectors; ref var depth = ref prepareParams.depth; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvInputMotionVectors, mvs.RenderTarget, mvs.MipLevel, mvs.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavReconstructedDepthPreviousFrame, Resources.ReconstructedDepth[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavDilatedDepth, Resources.DilatedDepth[frameIndex]); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); commandBuffer.EndSample(Sampler); } } internal class FrameInterpolationSetupPass : FrameInterpolationPass { public FrameInterpolationSetupPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Setup", contextDescription.shaders.setup); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { ref var scd = ref dispatchParams.opticalFlowSceneChangeDetection; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowSceneChangeDetection, scd.RenderTarget, scd.MipLevel, scd.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavGameMotionVectorFieldX, Resources.GameMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavGameMotionVectorFieldY, Resources.GameMotionVectorFieldY); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavOpticalFlowMotionVectorFieldX, Resources.OpticalFlowMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavOpticalFlowMotionVectorFieldY, Resources.OpticalFlowMotionVectorFieldY); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavDisocclusionMask, Resources.DisocclusionMask); commandBuffer.SetComputeBufferParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavCounters, Resources.Counters); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationReconstructPreviousDepthPass : FrameInterpolationPass { public FrameInterpolationReconstructPreviousDepthPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Reconstruct Previous Depth", contextDescription.shaders.reconstructPreviousDepth); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { // TODO: verify that we need the buffers from *this* frame (probably yes) commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDilatedDepth, Resources.DilatedDepth[frameIndex]); BindCurrentInterpolationSource(commandBuffer, dispatchParams); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavReconstructedDepthInterpolatedFrame, Resources.ReconstructedDepthInterpolatedFrame); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationGameMotionVectorFieldPass : FrameInterpolationPass { public FrameInterpolationGameMotionVectorFieldPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Game Motion Vector Field", contextDescription.shaders.gameMotionVectorField); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDilatedDepth, Resources.DilatedDepth[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvPreviousInterpolationSource, Resources.PreviousInterpolationSource); BindCurrentInterpolationSource(commandBuffer, dispatchParams); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavGameMotionVectorFieldX, Resources.GameMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavGameMotionVectorFieldY, Resources.GameMotionVectorFieldY); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationOpticalFlowVectorFieldPass : FrameInterpolationPass { public FrameInterpolationOpticalFlowVectorFieldPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Optical Flow Vector Field", contextDescription.shaders.opticalFlowVectorField); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { ref var ofVector = ref dispatchParams.opticalFlowVector; if (dispatchParams.opticalFlowScale.x > 0f) commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowVector, ofVector.RenderTarget, ofVector.MipLevel, ofVector.SubElement); else commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowVector, BuiltinRenderTextureType.None); // TODO this might error... if so, bind an empty placeholder resource commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowConfidence, BuiltinRenderTextureType.None); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDilatedDepth, Resources.DilatedDepth[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvPreviousInterpolationSource, Resources.PreviousInterpolationSource); BindCurrentInterpolationSource(commandBuffer, dispatchParams); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavOpticalFlowMotionVectorFieldX, Resources.OpticalFlowMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavOpticalFlowMotionVectorFieldY, Resources.OpticalFlowMotionVectorFieldY); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationDisocclusionMaskPass : FrameInterpolationPass { public FrameInterpolationDisocclusionMaskPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Disocclusion Mask", contextDescription.shaders.disocclusionMask); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldX, Resources.GameMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldY, Resources.GameMotionVectorFieldY); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvReconstructedDepthPreviousFrame, Resources.ReconstructedDepth[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDilatedDepth, Resources.DilatedDepth[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvReconstructedDepthInterpolatedFrame, Resources.ReconstructedDepthInterpolatedFrame); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvInpaintingPyramid, Resources.InpaintingPyramid); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavDisocclusionMask, Resources.DisocclusionMask); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationInterpolationPass : FrameInterpolationPass { public FrameInterpolationInterpolationPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Interpolation", contextDescription.shaders.interpolation); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldX, Resources.GameMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldY, Resources.GameMotionVectorFieldY); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowMotionVectorFieldX, Resources.OpticalFlowMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowMotionVectorFieldY, Resources.OpticalFlowMotionVectorFieldY); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvPreviousInterpolationSource, Resources.PreviousInterpolationSource); BindCurrentInterpolationSource(commandBuffer, dispatchParams); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDisocclusionMask, Resources.DisocclusionMask); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvInpaintingPyramid, Resources.InpaintingPyramid); commandBuffer.SetComputeBufferParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvCounters, Resources.Counters); ref var output = ref dispatchParams.output; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationInpaintingPyramidPass : FrameInterpolationPass { private readonly ComputeBuffer _spdConstants; public FrameInterpolationInpaintingPyramidPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants, ComputeBuffer spdConstants) : base(contextDescription, resources, constants) { _spdConstants = spdConstants; InitComputeShader("Inpainting Pyramid", contextDescription.shaders.inpaintingPyramid); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { ref var output = ref dispatchParams.output; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeBufferParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavCounters, Resources.Counters); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap0, Resources.InpaintingPyramid, 0); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap1, Resources.InpaintingPyramid, 1); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap2, Resources.InpaintingPyramid, 2); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap3, Resources.InpaintingPyramid, 3); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap4, Resources.InpaintingPyramid, 4); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap5, Resources.InpaintingPyramid, 5); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap6, Resources.InpaintingPyramid, 6); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap7, Resources.InpaintingPyramid, 7); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap8, Resources.InpaintingPyramid, 8); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap9, Resources.InpaintingPyramid, 9); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap10, Resources.InpaintingPyramid, 10); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap11, Resources.InpaintingPyramid, 11); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap12, Resources.InpaintingPyramid, 12); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationInpaintingPass : FrameInterpolationPass { public FrameInterpolationInpaintingPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Inpainting", contextDescription.shaders.inpainting); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { ref var scd = ref dispatchParams.opticalFlowSceneChangeDetection; ref var backBuf = ref dispatchParams.currentBackBuffer; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowSceneChangeDetection, scd.RenderTarget, scd.MipLevel, scd.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvInpaintingPyramid, Resources.InpaintingPyramid); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvPresentBackbuffer, backBuf.RenderTarget, backBuf.MipLevel, backBuf.SubElement); BindCurrentInterpolationSource(commandBuffer, dispatchParams); ref var output = ref dispatchParams.output; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationGameVectorFieldInpaintingPyramidPass : FrameInterpolationPass { private readonly ComputeBuffer _spdConstants; public FrameInterpolationGameVectorFieldInpaintingPyramidPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants, ComputeBuffer spdConstants) : base(contextDescription, resources, constants) { _spdConstants = spdConstants; InitComputeShader("Game Vector Field Inpainting Pyramid", contextDescription.shaders.gameVectorFieldInpaintingPyramid); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldX, Resources.GameMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldY, Resources.GameMotionVectorFieldY); commandBuffer.SetComputeBufferParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavCounters, Resources.Counters); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap0, Resources.InpaintingPyramid, 0); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap1, Resources.InpaintingPyramid, 1); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap2, Resources.InpaintingPyramid, 2); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap3, Resources.InpaintingPyramid, 3); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap4, Resources.InpaintingPyramid, 4); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap5, Resources.InpaintingPyramid, 5); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap6, Resources.InpaintingPyramid, 6); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap7, Resources.InpaintingPyramid, 7); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap8, Resources.InpaintingPyramid, 8); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap9, Resources.InpaintingPyramid, 9); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap10, Resources.InpaintingPyramid, 10); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap11, Resources.InpaintingPyramid, 11); BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap12, Resources.InpaintingPyramid, 12); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } internal class FrameInterpolationDebugViewPass : FrameInterpolationPass { public FrameInterpolationDebugViewPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { InitComputeShader("Debug View", contextDescription.shaders.debugView); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ) { ref var backBuf = ref dispatchParams.currentBackBuffer; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldX, Resources.GameMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvGameMotionVectorFieldY, Resources.GameMotionVectorFieldY); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowMotionVectorFieldX, Resources.OpticalFlowMotionVectorFieldX); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvOpticalFlowMotionVectorFieldY, Resources.OpticalFlowMotionVectorFieldY); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvDisocclusionMask, Resources.DisocclusionMask); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvPresentBackbuffer, backBuf.RenderTarget, backBuf.MipLevel, backBuf.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.SrvInpaintingPyramid, Resources.InpaintingPyramid); BindCurrentInterpolationSource(commandBuffer, dispatchParams); ref var output = ref dispatchParams.output; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, FrameInterpolationShaderIDs.UavOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } } }