diff --git a/Assets/Scripts/Fsr2Context.cs b/Assets/Scripts/Fsr2Context.cs index 94261ba..69eeaa1 100644 --- a/Assets/Scripts/Fsr2Context.cs +++ b/Assets/Scripts/Fsr2Context.cs @@ -68,13 +68,13 @@ namespace FidelityFX lanczos2Weights[currentLanczosWidthIndex] = (short)Mathf.Round(y * 32767.0f); } - InitPipelines(); - // TODO: create resources, i.e. render textures used for intermediate results. // Note that "aliasable" resources should be equivalent to GetTemporary render textures // UAVs *may* be an issue with the PS4 not handling simultaneous reading and writing to an RT properly // Unity does have Graphics.SetRandomWriteTarget for enabling UAV on ComputeBuffers or RTs // Unity doesn't do 1D textures so just default to Texture2D + + CreatePipelines(); } // private void InitShaders() @@ -90,9 +90,9 @@ namespace FidelityFX // LoadComputeShader("FSR2/ffx_fsr2_tcr_autogen_pass", ref _tcrAutogenShader, out _tcrAutogenKernel); // } - private void InitPipelines() + private void CreatePipelines() { - _computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer); + _computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer, _spdConstantsBuffer); _accumulatePipeline = new Fsr2AccumulatePipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer); _accumulateSharpenPipeline = new Fsr2AccumulateSharpenPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer); _rcasPipeline = new Fsr2RcasPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer, _rcasConstantsBuffer); @@ -100,15 +100,15 @@ namespace FidelityFX public void Destroy() { - DisposePipeline(ref _tcrAutogeneratePipeline); - DisposePipeline(ref _generateReactivePipeline); - DisposePipeline(ref _computeLuminancePyramidPipeline); - DisposePipeline(ref _rcasPipeline); - DisposePipeline(ref _accumulateSharpenPipeline); - DisposePipeline(ref _accumulatePipeline); - DisposePipeline(ref _lockPipeline); - DisposePipeline(ref _reconstructPreviousDepthPipeline); - DisposePipeline(ref _depthClipPipeline); + DestroyPipeline(ref _tcrAutogeneratePipeline); + DestroyPipeline(ref _generateReactivePipeline); + DestroyPipeline(ref _computeLuminancePyramidPipeline); + DestroyPipeline(ref _rcasPipeline); + DestroyPipeline(ref _accumulateSharpenPipeline); + DestroyPipeline(ref _accumulatePipeline); + DestroyPipeline(ref _lockPipeline); + DestroyPipeline(ref _reconstructPreviousDepthPipeline); + DestroyPipeline(ref _depthClipPipeline); DestroyConstantBuffer(ref _rcasConstantsBuffer); DestroyConstantBuffer(ref _spdConstantsBuffer); @@ -395,7 +395,7 @@ namespace FidelityFX bufferRef = null; } - private static void DisposePipeline(ref Fsr2Pipeline pipeline) + private static void DestroyPipeline(ref Fsr2Pipeline pipeline) { if (pipeline == null) return; diff --git a/Assets/Scripts/Fsr2Pipeline.cs b/Assets/Scripts/Fsr2Pipeline.cs index 25c1b83..73b3764 100644 --- a/Assets/Scripts/Fsr2Pipeline.cs +++ b/Assets/Scripts/Fsr2Pipeline.cs @@ -12,6 +12,27 @@ namespace FidelityFX protected ComputeShader ComputeShader; protected int KernelIndex; + + // Shader resource views, i.e. read-only bindings + protected static readonly int SrvInputColor = Shader.PropertyToID("r_input_color_jittered"); + protected static readonly int SrvOpaqueOnly = Shader.PropertyToID("r_input_opaque_only"); + 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 SrvRcasInput = Shader.PropertyToID("r_rcas_input"); + + // Unordered access views, i.e. random read/write bindings + protected static readonly int UavUpscaledOutput = Shader.PropertyToID("rw_upscaled_output"); + protected static readonly int UavExposureMipLumaChange = Shader.PropertyToID("rw_img_mip_shading_change"); + protected static readonly int UavExposureMip5 = Shader.PropertyToID("rw_img_mip_5"); + protected static readonly int UavAutoExposure = Shader.PropertyToID("rw_auto_exposure"); + protected static readonly int UavSpdAtomicCount = Shader.PropertyToID("rw_spd_global_atomic"); + + // Constant buffer bindings + protected static readonly int CbFsr2 = Shader.PropertyToID("cbFSR2"); + protected static readonly int CbSpd = Shader.PropertyToID("cbSPD"); + protected static readonly int CbRcas = Shader.PropertyToID("cbRCAS"); + protected static readonly int CbGenReactive = Shader.PropertyToID("cbGenerateReactive"); protected Fsr2Pipeline(Fsr2Callbacks callbacks, ComputeBuffer constants) { @@ -38,6 +59,7 @@ namespace FidelityFX kernelIndex = shaderRef.FindKernel("CS"); + // This mirrors the permutation rules from the CreatePipeline* functions if ((flags & Fsr2.InitializationFlags.EnableHighDynamicRange) != 0) shaderRef.EnableKeyword("FFX_FSR2_OPTION_HDR_COLOR_INPUT"); if ((flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) shaderRef.EnableKeyword("FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS"); if ((flags & Fsr2.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0) shaderRef.EnableKeyword("FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS"); @@ -63,15 +85,22 @@ namespace FidelityFX internal class Fsr2ComputeLuminancePyramidPipeline : Fsr2Pipeline { - public Fsr2ComputeLuminancePyramidPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants) + private readonly ComputeBuffer _spdConstants; + + public Fsr2ComputeLuminancePyramidPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants, ComputeBuffer spdConstants) : base(callbacks, constants) { + _spdConstants = spdConstants; + LoadComputeShader("FSR2/ffx_fsr2_compute_luminance_pyramid_pass", flags); } public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY) { - //throw new NotImplementedException(); + commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf()); + commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbSpd, _spdConstants, 0, Marshal.SizeOf()); + + commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); } } @@ -126,7 +155,7 @@ namespace FidelityFX internal class Fsr2RcasPipeline : Fsr2Pipeline { private readonly ComputeBuffer _rcasConstants; - + public Fsr2RcasPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants, ComputeBuffer rcasConstants) : base(callbacks, constants) { @@ -138,11 +167,11 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY) { // Run the RCAS sharpening filter on the upscaled image - ComputeShader.SetTexture(KernelIndex, "r_input_exposure", dispatchParams.Exposure); - ComputeShader.SetTexture(KernelIndex, "r_rcas_input", dispatchParams.Input); - ComputeShader.SetTexture(KernelIndex, "rw_upscaled_output", dispatchParams.Output); - ComputeShader.SetConstantBuffer("cbFSR2", Constants, 0, Marshal.SizeOf()); - ComputeShader.SetConstantBuffer("cbRCAS", _rcasConstants, 0, Marshal.SizeOf()); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvRcasInput, dispatchParams.Input); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output); + commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf()); + commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbRcas, _rcasConstants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); }