From 1b41f6b2d73d41765b3091262558c0eb455dcf4b Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Tue, 21 Feb 2023 14:45:03 +0100 Subject: [PATCH] Provide pipelines with the entire context description, which makes intiialization a bit simpler. Also provide it when registering resources so that the corrext *max* render size can be used. Started on the reconstruct depth pipeline. --- Assets/Scripts/Fsr2Context.cs | 16 ++++--- Assets/Scripts/Fsr2Controller.cs | 12 +++++ Assets/Scripts/Fsr2Pipeline.cs | 80 +++++++++++++++++++++++--------- 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/Assets/Scripts/Fsr2Context.cs b/Assets/Scripts/Fsr2Context.cs index bab4943..987bfa0 100644 --- a/Assets/Scripts/Fsr2Context.cs +++ b/Assets/Scripts/Fsr2Context.cs @@ -110,11 +110,11 @@ namespace FidelityFX private void CreatePipelines() { - _computeLuminancePyramidPipeline = - new Fsr2ComputeLuminancePyramidPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer, _spdConstantsBuffer, _autoExposureResource); - _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); + _computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline(_contextDescription, _fsr2ConstantsBuffer, _spdConstantsBuffer, _autoExposureResource); + _reconstructPreviousDepthPipeline = new Fsr2ReconstructPreviousDepthPipeline(_contextDescription, _fsr2ConstantsBuffer); + _accumulatePipeline = new Fsr2AccumulatePipeline(_contextDescription, _fsr2ConstantsBuffer); + _accumulateSharpenPipeline = new Fsr2AccumulateSharpenPipeline(_contextDescription, _fsr2ConstantsBuffer); + _rcasPipeline = new Fsr2RcasPipeline(_contextDescription, _fsr2ConstantsBuffer, _rcasConstantsBuffer); } public void Destroy() @@ -160,7 +160,7 @@ namespace FidelityFX bool resetAccumulation = dispatchParams.Reset || _firstExecution; _firstExecution = false; - Fsr2Pipeline.RegisterResources(_commandBuffer, dispatchParams); + Fsr2Pipeline.RegisterResources(_commandBuffer, _contextDescription, dispatchParams); SetupConstants(dispatchParams, resetAccumulation); @@ -174,7 +174,9 @@ namespace FidelityFX if (resetAccumulation) { // TODO: clear reconstructed depth for max depth store - + // UnityEngine.RenderTexture.active = myRenderTextureToClear; + // GL.Clear(true, true, Color.clear); // This is a rather bleh solution but apparently it works... + // CommandBuffer: SetRenderTarget, ClearRenderTarget } // Auto exposure diff --git a/Assets/Scripts/Fsr2Controller.cs b/Assets/Scripts/Fsr2Controller.cs index 971a8c9..3d7c174 100644 --- a/Assets/Scripts/Fsr2Controller.cs +++ b/Assets/Scripts/Fsr2Controller.cs @@ -28,6 +28,8 @@ public class Fsr2Controller : MonoBehaviour [HideInInspector] public float renderScale; + private bool _started; + private Vector2Int DisplaySize => new Vector2Int(Screen.width, Screen.height); private Vector2Int RenderSize => new Vector2Int(Mathf.FloorToInt(Screen.width * renderScale), Mathf.FloorToInt(Screen.height * renderScale)); @@ -53,8 +55,18 @@ public class Fsr2Controller : MonoBehaviour } } + private void Start() + { + _started = true; + OnEnable(); + } + private void OnEnable() { + // Delay OnEnable until we're sure all fields and properties are set + if (!_started) + return; + RenderPipelineManager.endContextRendering += OnEndContextRendering; // TODO: destroy and recreate context on screen resolution and/or quality mode change diff --git a/Assets/Scripts/Fsr2Pipeline.cs b/Assets/Scripts/Fsr2Pipeline.cs index cb11716..0126fb7 100644 --- a/Assets/Scripts/Fsr2Pipeline.cs +++ b/Assets/Scripts/Fsr2Pipeline.cs @@ -9,8 +9,8 @@ namespace FidelityFX internal abstract class Fsr2Pipeline: IDisposable { internal const int ShadingChangeMipLevel = 4; // Corresponds to FFX_FSR2_SHADING_CHANGE_MIP_LEVEL define - - private readonly Fsr2Callbacks _callbacks; + + protected readonly Fsr2.ContextDescription ContextDescription; protected readonly ComputeBuffer Constants; protected ComputeShader ComputeShader; @@ -37,9 +37,9 @@ namespace FidelityFX protected static readonly int CbRcas = Shader.PropertyToID("cbRCAS"); protected static readonly int CbGenReactive = Shader.PropertyToID("cbGenerateReactive"); - protected Fsr2Pipeline(Fsr2Callbacks callbacks, ComputeBuffer constants) + protected Fsr2Pipeline(Fsr2.ContextDescription contextDescription, ComputeBuffer constants) { - _callbacks = callbacks; + ContextDescription = contextDescription; Constants = constants; } @@ -50,17 +50,21 @@ namespace FidelityFX public abstract void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY); - public static void RegisterResources(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams) + public static void RegisterResources(CommandBuffer commandBuffer, Fsr2.ContextDescription contextDescription, Fsr2.DispatchDescription dispatchParams) { + Vector2Int displaySize = contextDescription.DisplaySize; + Vector2Int maxRenderSize = contextDescription.MaxRenderSize; + // Set up shared aliasable resources, i.e. temporary render textures - // These do not need to persist between frames, but they do need to be available between compute stages + // These do not need to persist between frames, but they do need to be available between passes // Resource FSR2_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE commandBuffer.GetTemporaryRT(UavSpdAtomicCount, 1, 1, 0, FilterMode.Point, GraphicsFormat.R32_UInt, 1, true); // Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE, has mipmap chain - commandBuffer.GetTemporaryRT(UavExposureMipLumaChange, dispatchParams.RenderSize.x >> (ShadingChangeMipLevel + 1), dispatchParams.RenderSize.y >> (ShadingChangeMipLevel + 1), 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); - commandBuffer.GetTemporaryRT(UavExposureMip5, dispatchParams.RenderSize.x >> 6, dispatchParams.RenderSize.y >> 6, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); + const int lumaMip = ShadingChangeMipLevel + 1; + commandBuffer.GetTemporaryRT(UavExposureMipLumaChange, maxRenderSize.x >> lumaMip, maxRenderSize.y >> lumaMip, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); + commandBuffer.GetTemporaryRT(UavExposureMip5, maxRenderSize.x >> 6, maxRenderSize.y >> 6, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); } public static void UnregisterResources(CommandBuffer commandBuffer) @@ -71,15 +75,15 @@ namespace FidelityFX commandBuffer.ReleaseTemporaryRT(UavExposureMip5); } - protected void LoadComputeShader(string name, Fsr2.InitializationFlags flags) + protected void LoadComputeShader(string name) { - LoadComputeShader(name, flags, ref ComputeShader, out KernelIndex); + LoadComputeShader(name, ContextDescription.Flags, ref ComputeShader, out KernelIndex); } private void LoadComputeShader(string name, Fsr2.InitializationFlags flags, ref ComputeShader shaderRef, out int kernelIndex) { if (shaderRef == null) - shaderRef = _callbacks.LoadComputeShader(name); + shaderRef = ContextDescription.Callbacks.LoadComputeShader(name); kernelIndex = shaderRef.FindKernel("CS"); @@ -104,7 +108,7 @@ namespace FidelityFX if (shaderRef == null) return; - _callbacks.UnloadComputeShader(shaderRef); + ContextDescription.Callbacks.UnloadComputeShader(shaderRef); shaderRef = null; } } @@ -114,13 +118,13 @@ namespace FidelityFX private readonly ComputeBuffer _spdConstants; private readonly RenderTexture _autoExposure; - public Fsr2ComputeLuminancePyramidPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants, ComputeBuffer spdConstants, RenderTexture autoExposure) - : base(callbacks, constants) + public Fsr2ComputeLuminancePyramidPipeline(Fsr2.ContextDescription contextDescription, ComputeBuffer constants, ComputeBuffer spdConstants, RenderTexture autoExposure) + : base(contextDescription, constants) { _spdConstants = spdConstants; _autoExposure = autoExposure; - LoadComputeShader("FSR2/ffx_fsr2_compute_luminance_pyramid_pass", flags); + LoadComputeShader("FSR2/ffx_fsr2_compute_luminance_pyramid_pass"); } public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY) @@ -140,12 +144,42 @@ namespace FidelityFX } } + internal class Fsr2ReconstructPreviousDepthPipeline : Fsr2Pipeline + { + public Fsr2ReconstructPreviousDepthPipeline(Fsr2.ContextDescription contextDescription, ComputeBuffer constants) + : base(contextDescription, constants) + { + LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass"); + } + + public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY) + { + /* +#define FSR2_BIND_SRV_INPUT_MOTION_VECTORS 0 +#define FSR2_BIND_SRV_INPUT_DEPTH 1 +#define FSR2_BIND_SRV_INPUT_COLOR 2 +#define FSR2_BIND_SRV_INPUT_EXPOSURE 3 + +#define FSR2_BIND_UAV_RECONSTRUCTED_PREV_NEAREST_DEPTH 0 +#define FSR2_BIND_UAV_DILATED_MOTION_VECTORS 1 +#define FSR2_BIND_UAV_DILATED_DEPTH 2 +#define FSR2_BIND_UAV_LOCK_INPUT_LUMA 3 + +#define FSR2_BIND_CB_FSR2 0 + */ + + commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf()); + + commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); + } + } + internal class Fsr2AccumulatePipeline : Fsr2Pipeline { - public Fsr2AccumulatePipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants) - : base(callbacks, constants) + public Fsr2AccumulatePipeline(Fsr2.ContextDescription contextDescription, ComputeBuffer constants) + : base(contextDescription, constants) { - LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass", flags); + LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass"); } public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY) @@ -158,8 +192,8 @@ namespace FidelityFX { private readonly ComputeShader _shaderCopy; - public Fsr2AccumulateSharpenPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants) - : base(callbacks, flags, constants) + public Fsr2AccumulateSharpenPipeline(Fsr2.ContextDescription contextDescription, ComputeBuffer constants) + : base(contextDescription, constants) { // Simply loading the accumulate_pass compute shader will give us the same instance as the non-sharpen pipeline // So we have to clone the shader instance and set the extra keyword on the new copy @@ -192,12 +226,12 @@ namespace FidelityFX { private readonly ComputeBuffer _rcasConstants; - public Fsr2RcasPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants, ComputeBuffer rcasConstants) - : base(callbacks, constants) + public Fsr2RcasPipeline(Fsr2.ContextDescription contextDescription, ComputeBuffer constants, ComputeBuffer rcasConstants) + : base(contextDescription, constants) { _rcasConstants = rcasConstants; - LoadComputeShader("FSR2/ffx_fsr2_rcas_pass", flags); + LoadComputeShader("FSR2/ffx_fsr2_rcas_pass"); } public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY)