diff --git a/Assets/Resources/FSR2/ffx_fsr2_depth_clip_pass.compute b/Assets/Resources/FSR2/ffx_fsr2_depth_clip_pass.compute index 88919d5..fdf09c6 100644 --- a/Assets/Resources/FSR2/ffx_fsr2_depth_clip_pass.compute +++ b/Assets/Resources/FSR2/ffx_fsr2_depth_clip_pass.compute @@ -11,4 +11,8 @@ #define FFX_GPU // Compiling for GPU #define FFX_HLSL // Compile for plain HLSL +// Monkey patch SRV names to match the UAV names from the shaders that output them +#define r_reconstructed_previous_nearest_depth rw_reconstructed_previous_nearest_depth +#define r_dilatedDepth rw_dilatedDepth + #include "shaders/ffx_fsr2_depth_clip_pass.hlsl" diff --git a/Assets/Scripts/Fsr2Context.cs b/Assets/Scripts/Fsr2Context.cs index 13578dd..7925591 100644 --- a/Assets/Scripts/Fsr2Context.cs +++ b/Assets/Scripts/Fsr2Context.cs @@ -121,6 +121,7 @@ namespace FidelityFX { _computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline(_contextDescription, _fsr2ConstantsBuffer, _spdConstantsBuffer, _autoExposureResource); _reconstructPreviousDepthPipeline = new Fsr2ReconstructPreviousDepthPipeline(_contextDescription, _fsr2ConstantsBuffer, _dilatedMotionVectorResources); + _depthClipPipeline = new Fsr2DepthClipPipeline(_contextDescription, _fsr2ConstantsBuffer, _dilatedMotionVectorResources); _accumulatePipeline = new Fsr2AccumulatePipeline(_contextDescription, _fsr2ConstantsBuffer); _accumulateSharpenPipeline = new Fsr2AccumulateSharpenPipeline(_contextDescription, _fsr2ConstantsBuffer); _rcasPipeline = new Fsr2RcasPipeline(_contextDescription, _fsr2ConstantsBuffer, _rcasConstantsBuffer); @@ -205,7 +206,7 @@ namespace FidelityFX _reconstructPreviousDepthPipeline.ScheduleDispatch(_commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Depth clip - // _commandBuffer.DispatchCompute(_depthClipShader, _depthClipKernel, dispatchSrcX, dispatchSrcY, 1); + _depthClipPipeline.ScheduleDispatch(_commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Create locks // _commandBuffer.DispatchCompute(_lockShader, _lockKernel, dispatchSrcX, dispatchSrcY, 1); diff --git a/Assets/Scripts/Fsr2Controller.cs b/Assets/Scripts/Fsr2Controller.cs index d6ac813..5139eeb 100644 --- a/Assets/Scripts/Fsr2Controller.cs +++ b/Assets/Scripts/Fsr2Controller.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using FidelityFX; using UnityEngine; +using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; /// @@ -38,7 +39,7 @@ public class Fsr2Controller : MonoBehaviour private RenderTexture _colorRT, _depthRT, _motionVectorsRT; private RenderTexture _outputRT; - private Texture2D _exposure; + private Texture2D _defaultExposure, _defaultReactive; private Material _copyDepthMat; private Material CopyDepthMaterial @@ -92,17 +93,22 @@ public class Fsr2Controller : MonoBehaviour _outputRT = new RenderTexture(DisplaySize.x, DisplaySize.y, 24, RenderTextureFormat.ARGBHalf) { enableRandomWrite = true }; _outputRT.Create(); - _exposure = new Texture2D(1, 1) { name = "FSR2 Exposure" }; - _exposure.SetPixel(0, 0, Color.white); - _exposure.Apply(); + // TODO: move these defaults to Fsr2Context, provide nulls in dispatch + _defaultExposure = new Texture2D(1, 1, GraphicsFormat.R32G32_SFloat, TextureCreationFlags.None) { name = "FSR2 Default Exposure" }; + _defaultExposure.SetPixel(0, 0, Color.black); + _defaultExposure.Apply(); + + _defaultReactive = new Texture2D(1, 1, GraphicsFormat.R8_UNorm, TextureCreationFlags.None) { name = "FSR2 Default Reactive Mask" }; + _defaultReactive.SetPixel(0, 0, Color.black); + _defaultReactive.Apply(); } private void OnDisable() { - if (_exposure != null) + if (_defaultExposure != null) { - Destroy(_exposure); - _exposure = null; + Destroy(_defaultExposure); + _defaultExposure = null; } if (_outputRT != null) @@ -150,7 +156,8 @@ public class Fsr2Controller : MonoBehaviour _dispatchDescription.Depth = _depthRT; _dispatchDescription.MotionVectors = _motionVectorsRT; _dispatchDescription.Output = _outputRT; - _dispatchDescription.Exposure = _exposure; + _dispatchDescription.Exposure = _defaultExposure; + _dispatchDescription.Reactive = _defaultReactive; _dispatchDescription.PreExposure = 1.0f; _dispatchDescription.EnableSharpening = performSharpenPass; _dispatchDescription.Sharpness = sharpness; diff --git a/Assets/Scripts/Fsr2Pipeline.cs b/Assets/Scripts/Fsr2Pipeline.cs index 6236859..52bed8d 100644 --- a/Assets/Scripts/Fsr2Pipeline.cs +++ b/Assets/Scripts/Fsr2Pipeline.cs @@ -22,6 +22,11 @@ namespace FidelityFX protected static readonly int SrvInputMotionVectors = Shader.PropertyToID("r_input_motion_vectors"); protected static readonly int SrvInputDepth = Shader.PropertyToID("r_input_depth"); protected static readonly int SrvInputExposure = Shader.PropertyToID("r_input_exposure"); + protected static readonly int SrvDilatedMotionVectors = Shader.PropertyToID("r_dilated_motion_vectors"); + protected static readonly int SrvDilatedDepth = Shader.PropertyToID("r_dilatedDepth"); + protected static readonly int SrvReactiveMask = Shader.PropertyToID("r_reactive_mask"); + protected static readonly int SrvTransparencyAndCompositionMask = Shader.PropertyToID("r_transparency_and_composition_mask"); + protected static readonly int SrvPrevDilatedMotionVectors = Shader.PropertyToID("r_previous_dilated_motion_vectors"); protected static readonly int SrvRcasInput = Shader.PropertyToID("r_rcas_input"); // Unordered access views, i.e. random read/write bindings @@ -34,6 +39,8 @@ namespace FidelityFX protected static readonly int UavDilatedMotionVectors = Shader.PropertyToID("rw_dilated_motion_vectors"); protected static readonly int UavDilatedDepth = Shader.PropertyToID("rw_dilatedDepth"); protected static readonly int UavLockInputLuma = Shader.PropertyToID("rw_lock_input_luma"); + protected static readonly int UavDilatedReactiveMasks = Shader.PropertyToID("rw_dilated_reactive_masks"); + protected static readonly int UavPreparedInputColor = Shader.PropertyToID("rw_prepared_input_color"); // Constant buffer bindings protected static readonly int CbFsr2 = Shader.PropertyToID("cbFSR2"); @@ -77,7 +84,14 @@ namespace FidelityFX commandBuffer.GetTemporaryRT(UavDilatedDepth, maxRenderSize.x, maxRenderSize.y, 0, FilterMode.Point, GraphicsFormat.R32_SFloat, 1, true); // FSR2_LockInputLuma: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE + // TODO: should be at render resolution according to the docs (at least when output from Reconstruct & Dilate) commandBuffer.GetTemporaryRT(UavLockInputLuma, displaySize.x, displaySize.y, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); + + // FSR2_DilatedReactiveMasks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE + commandBuffer.GetTemporaryRT(UavDilatedReactiveMasks, maxRenderSize.x, maxRenderSize.y, 0, FilterMode.Point, GraphicsFormat.R8G8_UNorm, 1, true); + + // FSR2_PreparedInputColor: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE + commandBuffer.GetTemporaryRT(UavPreparedInputColor, maxRenderSize.x, maxRenderSize.y, 0, FilterMode.Point, GraphicsFormat.R16G16B16A16_SFloat, 1, true); } public static void UnregisterResources(CommandBuffer commandBuffer) @@ -186,6 +200,35 @@ namespace FidelityFX commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); } } + + internal class Fsr2DepthClipPipeline : Fsr2Pipeline + { + private readonly RenderTexture[] _dilatedMotionVectors; + + public Fsr2DepthClipPipeline(Fsr2.ContextDescription contextDescription, ComputeBuffer constants, RenderTexture[] dilatedMotionVectors) + : base(contextDescription, constants) + { + _dilatedMotionVectors = dilatedMotionVectors; + + LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass"); + } + + public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) + { + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvDilatedMotionVectors, _dilatedMotionVectors[frameIndex]); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvReactiveMask, dispatchParams.Reactive); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvTransparencyAndCompositionMask, dispatchParams.Reactive); // Default reactive mask, as we don't support TCR (yet) + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvPrevDilatedMotionVectors, _dilatedMotionVectors[frameIndex ^ 1]); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.Color); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputDepth, dispatchParams.Depth); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure); + + commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf()); + + commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); + } + } internal class Fsr2AccumulatePipeline : Fsr2Pipeline {