From 982c41cc203ba2ba1ce8238b5f9626602bc76bcd Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Fri, 6 Oct 2023 16:09:52 +0200 Subject: [PATCH] Refactoring work: - Reworked input/output resource management using a new ResourceView struct, which encompasses all relevant data required to bind textures from various sources. This eliminates the need for resource binding code outside of the core FSR2 classes, and makes the public API more strict and consistent, but also more flexible. In addition, it allows the input/output resource debug checks to happen every frame for that frame. - Changed prebaked RCAS configurations into an array, as there is no need for a dynamically sized list here. - Renamed Pipelines to Passes. --- Assets/Scripts/Core/Fsr2.cs | 57 +++++-- Assets/Scripts/Core/Fsr2Context.cs | 145 ++++++++-------- .../Core/{Fsr2Pipeline.cs => Fsr2Pass.cs} | 159 +++++++++--------- ...{Fsr2Pipeline.cs.meta => Fsr2Pass.cs.meta} | 0 Assets/Scripts/Fsr2ImageEffect.cs | 34 ++-- .../Runtime/Effects/SuperResolution.cs | 39 ++--- .../PostProcessing/Runtime/FSR2/Fsr2.cs | 64 +++++-- .../Runtime/FSR2/Fsr2Context.cs | 145 ++++++++-------- .../FSR2/{Fsr2Pipeline.cs => Fsr2Pass.cs} | 159 +++++++++--------- ...{Fsr2Pipeline.cs.meta => Fsr2Pass.cs.meta} | 0 10 files changed, 423 insertions(+), 379 deletions(-) rename Assets/Scripts/Core/{Fsr2Pipeline.cs => Fsr2Pass.cs} (69%) rename Assets/Scripts/Core/{Fsr2Pipeline.cs.meta => Fsr2Pass.cs.meta} (100%) rename com.unity.postprocessing/PostProcessing/Runtime/FSR2/{Fsr2Pipeline.cs => Fsr2Pass.cs} (69%) rename com.unity.postprocessing/PostProcessing/Runtime/FSR2/{Fsr2Pipeline.cs.meta => Fsr2Pass.cs.meta} (100%) diff --git a/Assets/Scripts/Core/Fsr2.cs b/Assets/Scripts/Core/Fsr2.cs index 51caa32..1ba8192 100644 --- a/Assets/Scripts/Core/Fsr2.cs +++ b/Assets/Scripts/Core/Fsr2.cs @@ -162,20 +162,50 @@ namespace FidelityFX public Vector2Int DisplaySize; public IFsr2Callbacks Callbacks; } + + /// + /// An immutable structure wrapping all of the necessary information to bind a specific buffer or attachment of a render target to a compute shader. + /// + public readonly struct ResourceView + { + /// + /// This value is the equivalent of not setting any value at all; all struct fields will have their default values. + /// It does not refer to a valid texture, therefore any variable set to this value should be checked for IsValid and reassigned before being bound to a shader. + /// + public static readonly ResourceView Unassigned = new ResourceView(default); + + /// + /// This value contains a valid texture reference that can be bound to a shader, however it is just an empty placeholder texture. + /// Binding this to a shader can be seen as setting the texture variable inside the shader to null. + /// + public static readonly ResourceView None = new ResourceView(BuiltinRenderTextureType.None); + + public ResourceView(in RenderTargetIdentifier renderTarget, RenderTextureSubElement subElement = RenderTextureSubElement.Default, int mipLevel = 0) + { + RenderTarget = renderTarget; + SubElement = subElement; + MipLevel = mipLevel; + } + + public bool IsValid => !RenderTarget.Equals(default); + + public readonly RenderTargetIdentifier RenderTarget; + public readonly RenderTextureSubElement SubElement; + public readonly int MipLevel; + } /// - /// The input and output resources are all optional. If they are null, the Fsr2Context won't try to bind them to any shaders. - /// This allows for customized and more efficient resource management outside of Fsr2Context, tailored to the specific scenario. + /// A structure encapsulating the parameters for dispatching the various passes of FidelityFX Super Resolution 2. /// public class DispatchDescription { - public RenderTargetIdentifier? Color; - public RenderTargetIdentifier? Depth; - public RenderTargetIdentifier? MotionVectors; - public RenderTargetIdentifier? Exposure; - public RenderTargetIdentifier? Reactive; - public RenderTargetIdentifier? TransparencyAndComposition; - public RenderTargetIdentifier? Output; + public ResourceView Color; + public ResourceView Depth; + public ResourceView MotionVectors; + public ResourceView Exposure; // optional + public ResourceView Reactive; // optional + public ResourceView TransparencyAndComposition; // optional + public ResourceView Output; public Vector2 JitterOffset; public Vector2 MotionVectorScale; public Vector2Int RenderSize; @@ -192,7 +222,7 @@ namespace FidelityFX // EXPERIMENTAL reactive mask generation parameters public bool EnableAutoReactive; - public RenderTargetIdentifier? ColorOpaqueOnly; + public ResourceView ColorOpaqueOnly; public float AutoTcThreshold = 0.05f; public float AutoTcScale = 1.0f; public float AutoReactiveScale = 5.0f; @@ -200,13 +230,14 @@ namespace FidelityFX } /// + /// A structure encapsulating the parameters for automatic generation of a reactive mask. /// The default values for Scale, CutoffThreshold, BinaryValue and Flags were taken from the FSR2 demo project. /// public class GenerateReactiveDescription { - public RenderTargetIdentifier? ColorOpaqueOnly; - public RenderTargetIdentifier? ColorPreUpscale; - public RenderTargetIdentifier? OutReactive; + public ResourceView ColorOpaqueOnly; + public ResourceView ColorPreUpscale; + public ResourceView OutReactive; public Vector2Int RenderSize; public float Scale = 0.5f; public float CutoffThreshold = 0.2f; diff --git a/Assets/Scripts/Core/Fsr2Context.cs b/Assets/Scripts/Core/Fsr2Context.cs index b1d9a17..5c8975c 100644 --- a/Assets/Scripts/Core/Fsr2Context.cs +++ b/Assets/Scripts/Core/Fsr2Context.cs @@ -39,14 +39,14 @@ namespace FidelityFX private Fsr2.ContextDescription _contextDescription; private CommandBuffer _commandBuffer; - private Fsr2Pipeline _depthClipPipeline; - private Fsr2Pipeline _reconstructPreviousDepthPipeline; - private Fsr2Pipeline _lockPipeline; - private Fsr2Pipeline _accumulatePipeline; - private Fsr2Pipeline _rcasPipeline; - private Fsr2Pipeline _computeLuminancePyramidPipeline; - private Fsr2Pipeline _generateReactivePipeline; - private Fsr2Pipeline _tcrAutogeneratePipeline; + private Fsr2Pass _depthClipPass; + private Fsr2Pass _reconstructPreviousDepthPass; + private Fsr2Pass _lockPass; + private Fsr2Pass _accumulatePass; + private Fsr2Pass _rcasPass; + private Fsr2Pass _computeLuminancePyramidPass; + private Fsr2Pass _generateReactivePass; + private Fsr2Pass _tcrAutogeneratePass; private readonly Fsr2Resources _resources = new Fsr2Resources(); @@ -92,31 +92,31 @@ namespace FidelityFX Constants.displaySize = _contextDescription.DisplaySize; _resources.Create(_contextDescription); - CreatePipelines(); + CreatePasses(); } - private void CreatePipelines() + private void CreatePasses() { - _computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer, _spdConstantsBuffer); - _reconstructPreviousDepthPipeline = new Fsr2ReconstructPreviousDepthPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _depthClipPipeline = new Fsr2DepthClipPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _lockPipeline = new Fsr2LockPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _accumulatePipeline = new Fsr2AccumulatePipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _rcasPipeline = new Fsr2RcasPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer, _rcasConstantsBuffer); - _generateReactivePipeline = new Fsr2GenerateReactivePipeline(_contextDescription, _resources, _generateReactiveConstantsBuffer); - _tcrAutogeneratePipeline = new Fsr2TcrAutogeneratePipeline(_contextDescription, _resources, _fsr2ConstantsBuffer, _tcrAutogenerateConstantsBuffer); + _computeLuminancePyramidPass = new Fsr2ComputeLuminancePyramidPass(_contextDescription, _resources, _fsr2ConstantsBuffer, _spdConstantsBuffer); + _reconstructPreviousDepthPass = new Fsr2ReconstructPreviousDepthPass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _depthClipPass = new Fsr2DepthClipPass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _lockPass = new Fsr2LockPass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _accumulatePass = new Fsr2AccumulatePass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _rcasPass = new Fsr2RcasPass(_contextDescription, _resources, _fsr2ConstantsBuffer, _rcasConstantsBuffer); + _generateReactivePass = new Fsr2GenerateReactivePass(_contextDescription, _resources, _generateReactiveConstantsBuffer); + _tcrAutogeneratePass = new Fsr2TcrAutogeneratePass(_contextDescription, _resources, _fsr2ConstantsBuffer, _tcrAutogenerateConstantsBuffer); } public void Destroy() { - DestroyPipeline(ref _tcrAutogeneratePipeline); - DestroyPipeline(ref _generateReactivePipeline); - DestroyPipeline(ref _computeLuminancePyramidPipeline); - DestroyPipeline(ref _rcasPipeline); - DestroyPipeline(ref _accumulatePipeline); - DestroyPipeline(ref _lockPipeline); - DestroyPipeline(ref _reconstructPreviousDepthPipeline); - DestroyPipeline(ref _depthClipPipeline); + DestroyPass(ref _tcrAutogeneratePass); + DestroyPass(ref _generateReactivePass); + DestroyPass(ref _computeLuminancePyramidPass); + DestroyPass(ref _rcasPass); + DestroyPass(ref _accumulatePass); + DestroyPass(ref _lockPass); + DestroyPass(ref _reconstructPreviousDepthPass); + DestroyPass(ref _depthClipPass); _resources.Destroy(); @@ -158,18 +158,21 @@ namespace FidelityFX // If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends if ((_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) - dispatchParams.Exposure = _resources.AutoExposure; - else if (dispatchParams.Exposure == null) - dispatchParams.Exposure = _resources.DefaultExposure; + dispatchParams.Exposure = new Fsr2.ResourceView(_resources.AutoExposure); + else if (!dispatchParams.Exposure.IsValid) + dispatchParams.Exposure = new Fsr2.ResourceView(_resources.DefaultExposure); if (dispatchParams.EnableAutoReactive) { // Create the auto-TCR resources only when we need them if (_resources.AutoReactive == null) _resources.CreateTcrAutogenResources(_contextDescription); - + if (resetAccumulation) - commandBuffer.Blit(_resources.PrevPreAlpha[frameIndex ^ 1], dispatchParams.ColorOpaqueOnly ?? Fsr2ShaderIDs.SrvOpaqueOnly); + { + RenderTargetIdentifier opaqueOnly = dispatchParams.ColorOpaqueOnly.IsValid ? dispatchParams.ColorOpaqueOnly.RenderTarget : Fsr2ShaderIDs.SrvOpaqueOnly; + commandBuffer.Blit(_resources.PrevPreAlpha[frameIndex ^ 1], opaqueOnly); + } } else if (_resources.AutoReactive != null) { @@ -177,8 +180,8 @@ namespace FidelityFX _resources.DestroyTcrAutogenResources(); } - if (dispatchParams.Reactive == null) dispatchParams.Reactive = _resources.DefaultReactive; - if (dispatchParams.TransparencyAndComposition == null) dispatchParams.TransparencyAndComposition = _resources.DefaultReactive; + if (!dispatchParams.Reactive.IsValid) dispatchParams.Reactive = new Fsr2.ResourceView(_resources.DefaultReactive); + if (!dispatchParams.TransparencyAndComposition.IsValid) dispatchParams.TransparencyAndComposition = new Fsr2.ResourceView(_resources.DefaultReactive); Fsr2Resources.CreateAliasableResources(commandBuffer, _contextDescription, dispatchParams); SetupConstants(dispatchParams, resetAccumulation); @@ -222,24 +225,24 @@ namespace FidelityFX if (dispatchParams.EnableAutoReactive) { GenerateTransparencyCompositionReactive(dispatchParams, commandBuffer, frameIndex); - dispatchParams.Reactive = _resources.AutoReactive; - dispatchParams.TransparencyAndComposition = _resources.AutoComposition; + dispatchParams.Reactive = new Fsr2.ResourceView(_resources.AutoReactive); + dispatchParams.TransparencyAndComposition = new Fsr2.ResourceView(_resources.AutoComposition); } // Compute luminance pyramid - _computeLuminancePyramidPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); + _computeLuminancePyramidPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); // Reconstruct previous depth - _reconstructPreviousDepthPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _reconstructPreviousDepthPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Depth clip - _depthClipPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _depthClipPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Create locks - _lockPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _lockPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Accumulate - _accumulatePipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY); + _accumulatePass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY); if (dispatchParams.EnableSharpening) { @@ -251,7 +254,7 @@ namespace FidelityFX const int threadGroupWorkRegionDimRcas = 16; int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; - _rcasPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY); + _rcasPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY); } _resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames; @@ -278,7 +281,7 @@ namespace FidelityFX GenReactiveConsts.flags = (uint)dispatchParams.Flags; commandBuffer.SetBufferData(_generateReactiveConstantsBuffer, _generateReactiveConstantsArray); - ((Fsr2GenerateReactivePipeline)_generateReactivePipeline).ScheduleDispatch(commandBuffer, dispatchParams, dispatchSrcX, dispatchSrcY); + ((Fsr2GenerateReactivePass)_generateReactivePass).ScheduleDispatch(commandBuffer, dispatchParams, dispatchSrcX, dispatchSrcY); } private void GenerateTransparencyCompositionReactive(Fsr2.DispatchDescription dispatchParams, CommandBuffer commandBuffer, int frameIndex) @@ -293,7 +296,7 @@ namespace FidelityFX TcrAutoGenConsts.autoReactiveMax = dispatchParams.AutoReactiveMax; commandBuffer.SetBufferData(_tcrAutogenerateConstantsBuffer, _tcrAutogenerateConstantsArray); - _tcrAutogeneratePipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _tcrAutogeneratePass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); } private void SetupConstants(Fsr2.DispatchDescription dispatchParams, bool resetAccumulation) @@ -353,7 +356,7 @@ namespace FidelityFX constants.frameIndex++; // Shading change usage of the SPD mip levels - constants.lumaMipLevelToUse = Fsr2Pipeline.ShadingChangeMipLevel; + constants.lumaMipLevelToUse = Fsr2Pass.ShadingChangeMipLevel; float mipDiv = 2 << constants.lumaMipLevelToUse; constants.lumaMipDimensions.x = (int)(constants.maxRenderSize.x / mipDiv); @@ -395,7 +398,7 @@ namespace FidelityFX private void SetupRcasConstants(Fsr2.DispatchDescription dispatchParams) { - int sharpnessIndex = Mathf.RoundToInt(Mathf.Clamp01(dispatchParams.Sharpness) * (RcasConfigs.Count - 1)); + int sharpnessIndex = Mathf.RoundToInt(Mathf.Clamp01(dispatchParams.Sharpness) * (RcasConfigs.Length - 1)); RcasConsts = RcasConfigs[sharpnessIndex]; } @@ -433,31 +436,27 @@ namespace FidelityFX private void DebugCheckDispatch(Fsr2.DispatchDescription dispatchParams) { - // Global texture binding may be queued as part of the command list, which is why we check these after running the process at least once - if (!_firstExecution && !dispatchParams.Reset) + if (!dispatchParams.Color.IsValid) { - if (!dispatchParams.Color.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputColor) == null) - { - Debug.LogError("Color resource is null"); - } - - if (!dispatchParams.Depth.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputDepth) == null) - { - Debug.LogError("Depth resource is null"); - } - - if (!dispatchParams.MotionVectors.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputMotionVectors) == null) - { - Debug.LogError("MotionVectors resource is null"); - } - - if (!dispatchParams.Output.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.UavUpscaledOutput) == null) - { - Debug.LogError("Output resource is null"); - } + Debug.LogError("Color resource is null"); } - - if (dispatchParams.Exposure.HasValue && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) + + if (!dispatchParams.Depth.IsValid) + { + Debug.LogError("Depth resource is null"); + } + + if (!dispatchParams.MotionVectors.IsValid) + { + Debug.LogError("MotionVectors resource is null"); + } + + if (!dispatchParams.Output.IsValid) + { + Debug.LogError("Output resource is null"); + } + + if (dispatchParams.Exposure.IsValid && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) { Debug.LogWarning("Exposure resource provided, however auto exposure flag is present"); } @@ -556,7 +555,7 @@ namespace FidelityFX /// The FSR2 C++ codebase uses floats bitwise converted to ints to pass sharpness parameters to the RCAS shader. /// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values. /// - private static readonly List RcasConfigs = new List() + private static readonly Fsr2.RcasConstants[] RcasConfigs = new [] { new Fsr2.RcasConstants(1048576000u, 872428544u), new Fsr2.RcasConstants(1049178080u, 877212745u), @@ -595,13 +594,13 @@ namespace FidelityFX bufferRef = null; } - private static void DestroyPipeline(ref Fsr2Pipeline pipeline) + private static void DestroyPass(ref Fsr2Pass pass) { - if (pipeline == null) + if (pass == null) return; - pipeline.Dispose(); - pipeline = null; + pass.Dispose(); + pass = null; } } } diff --git a/Assets/Scripts/Core/Fsr2Pipeline.cs b/Assets/Scripts/Core/Fsr2Pass.cs similarity index 69% rename from Assets/Scripts/Core/Fsr2Pipeline.cs rename to Assets/Scripts/Core/Fsr2Pass.cs index 5b963f0..23b8e6c 100644 --- a/Assets/Scripts/Core/Fsr2Pipeline.cs +++ b/Assets/Scripts/Core/Fsr2Pass.cs @@ -30,7 +30,7 @@ namespace FidelityFX /// This loosely matches the FfxPipelineState struct from the original FSR2 codebase, wrapped in an object-oriented blanket. /// These classes are responsible for loading compute shaders, managing temporary resources, binding resources to shader kernels and dispatching said shaders. /// - internal abstract class Fsr2Pipeline: IDisposable + internal abstract class Fsr2Pass: IDisposable { internal const int ShadingChangeMipLevel = 4; // This matches the FFX_FSR2_SHADING_CHANGE_MIP_LEVEL define @@ -43,7 +43,7 @@ namespace FidelityFX protected virtual bool AllowFP16 => true; - protected Fsr2Pipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + protected Fsr2Pass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) { ContextDescription = contextDescription; Resources = resources; @@ -115,11 +115,11 @@ namespace FidelityFX } } - internal class Fsr2ComputeLuminancePyramidPipeline : Fsr2Pipeline + internal class Fsr2ComputeLuminancePyramidPass : Fsr2Pass { private readonly ComputeBuffer _spdConstants; - public Fsr2ComputeLuminancePyramidPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer spdConstants) + public Fsr2ComputeLuminancePyramidPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer spdConstants) : base(contextDescription, resources, constants) { _spdConstants = spdConstants; @@ -129,8 +129,8 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); + ref var color = ref dispatchParams.Color; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavSpdAtomicCount, Resources.SpdAtomicCounter); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel); @@ -144,9 +144,9 @@ namespace FidelityFX } } - internal class Fsr2ReconstructPreviousDepthPipeline : Fsr2Pipeline + internal class Fsr2ReconstructPreviousDepthPass : Fsr2Pass { - public Fsr2ReconstructPreviousDepthPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2ReconstructPreviousDepthPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass"); @@ -154,18 +154,16 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.Depth.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, dispatchParams.Depth.Value, 0, RenderTextureSubElement.Depth); - - if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); + ref var color = ref dispatchParams.Color; + ref var depth = ref dispatchParams.Depth; + ref var motionVectors = ref dispatchParams.MotionVectors; + ref var exposure = ref dispatchParams.Exposure; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf()); @@ -174,9 +172,9 @@ namespace FidelityFX } } - internal class Fsr2DepthClipPipeline : Fsr2Pipeline + internal class Fsr2DepthClipPass : Fsr2Pass { - public Fsr2DepthClipPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2DepthClipPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass"); @@ -184,24 +182,20 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.Depth.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, dispatchParams.Depth.Value, 0, RenderTextureSubElement.Depth); - - if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); + ref var color = ref dispatchParams.Color; + ref var depth = ref dispatchParams.Depth; + ref var motionVectors = ref dispatchParams.MotionVectors; + ref var exposure = ref dispatchParams.Exposure; + ref var reactive = ref dispatchParams.Reactive; + ref var tac = ref dispatchParams.TransparencyAndComposition; + + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, tac.RenderTarget, tac.MipLevel, tac.SubElement); - if (dispatchParams.Reactive.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, dispatchParams.Reactive.Value); - - if (dispatchParams.TransparencyAndComposition.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, dispatchParams.TransparencyAndComposition.Value); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReconstructedPrevNearestDepth, Fsr2ShaderIDs.UavReconstructedPrevNearestDepth); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedDepth, Fsr2ShaderIDs.UavDilatedDepth); @@ -213,9 +207,9 @@ namespace FidelityFX } } - internal class Fsr2LockPipeline : Fsr2Pipeline + internal class Fsr2LockPass : Fsr2Pass { - public Fsr2LockPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2LockPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_lock_pass"); @@ -230,7 +224,7 @@ namespace FidelityFX } } - internal class Fsr2AccumulatePipeline : Fsr2Pipeline + internal class Fsr2AccumulatePass : Fsr2Pass { private const string SharpeningKeyword = "FFX_FSR2_OPTION_APPLY_SHARPENING"; @@ -241,7 +235,7 @@ namespace FidelityFX private readonly LocalKeyword _sharpeningKeyword; #endif - public Fsr2AccumulatePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2AccumulatePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass"); @@ -265,13 +259,18 @@ namespace FidelityFX #endif if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) + { commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); - else if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); - + } + else + { + ref var motionVectors = ref dispatchParams.MotionVectors; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); + } + + ref var exposure = ref dispatchParams.Exposure; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedReactiveMasks, Fsr2ShaderIDs.UavDilatedReactiveMasks); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvLockStatus, Resources.LockStatus[frameIndex ^ 1]); @@ -286,8 +285,8 @@ namespace FidelityFX commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLumaHistory, Resources.LumaHistory[frameIndex]); - if (dispatchParams.Output.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, dispatchParams.Output.Value); + ref var output = ref dispatchParams.Output; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf()); @@ -295,11 +294,11 @@ namespace FidelityFX } } - internal class Fsr2RcasPipeline : Fsr2Pipeline + internal class Fsr2RcasPass : Fsr2Pass { private readonly ComputeBuffer _rcasConstants; - public Fsr2RcasPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer rcasConstants) + public Fsr2RcasPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer rcasConstants) : base(contextDescription, resources, constants) { _rcasConstants = rcasConstants; @@ -309,13 +308,12 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); - + ref var exposure = ref dispatchParams.Exposure; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvRcasInput, Resources.InternalUpscaled[frameIndex]); - if (dispatchParams.Output.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, dispatchParams.Output.Value); + ref var output = ref dispatchParams.Output; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbRcas, _rcasConstants, 0, Marshal.SizeOf()); @@ -324,11 +322,11 @@ namespace FidelityFX } } - internal class Fsr2GenerateReactivePipeline : Fsr2Pipeline + internal class Fsr2GenerateReactivePass : Fsr2Pass { private readonly ComputeBuffer _generateReactiveConstants; - public Fsr2GenerateReactivePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer generateReactiveConstants) + public Fsr2GenerateReactivePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer generateReactiveConstants) : base(contextDescription, resources, null) { _generateReactiveConstants = generateReactiveConstants; @@ -342,14 +340,13 @@ namespace FidelityFX public void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.GenerateReactiveDescription dispatchParams, int dispatchX, int dispatchY) { - if (dispatchParams.ColorOpaqueOnly.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, dispatchParams.ColorOpaqueOnly.Value, 0, RenderTextureSubElement.Color); + ref var opaqueOnly = ref dispatchParams.ColorOpaqueOnly; + ref var color = ref dispatchParams.ColorPreUpscale; + ref var reactive = ref dispatchParams.OutReactive; - if (dispatchParams.ColorPreUpscale.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.ColorPreUpscale.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.OutReactive.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoReactive, dispatchParams.OutReactive.Value); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, opaqueOnly.RenderTarget, opaqueOnly.MipLevel, opaqueOnly.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoReactive, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbGenReactive, _generateReactiveConstants, 0, Marshal.SizeOf()); @@ -357,11 +354,11 @@ namespace FidelityFX } } - internal class Fsr2TcrAutogeneratePipeline : Fsr2Pipeline + internal class Fsr2TcrAutogeneratePass : Fsr2Pass { private readonly ComputeBuffer _tcrAutogenerateConstants; - public Fsr2TcrAutogeneratePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer tcrAutogenerateConstants) + public Fsr2TcrAutogeneratePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer tcrAutogenerateConstants) : base(contextDescription, resources, constants) { _tcrAutogenerateConstants = tcrAutogenerateConstants; @@ -371,23 +368,19 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.ColorOpaqueOnly.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, dispatchParams.ColorOpaqueOnly.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - + ref var color = ref dispatchParams.Color; + ref var motionVectors = ref dispatchParams.MotionVectors; + ref var opaqueOnly = ref dispatchParams.ColorOpaqueOnly; + ref var reactive = ref dispatchParams.Reactive; + ref var tac = ref dispatchParams.TransparencyAndComposition; + + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, opaqueOnly.RenderTarget, opaqueOnly.MipLevel, opaqueOnly.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvPrevColorPreAlpha, Resources.PrevPreAlpha[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvPrevColorPostAlpha, Resources.PrevPostAlpha[frameIndex ^ 1]); - - if (dispatchParams.Reactive.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, dispatchParams.Reactive.Value); - - if (dispatchParams.TransparencyAndComposition.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, dispatchParams.TransparencyAndComposition.Value); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, tac.RenderTarget, tac.MipLevel, tac.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoReactive, Resources.AutoReactive); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoComposition, Resources.AutoComposition); diff --git a/Assets/Scripts/Core/Fsr2Pipeline.cs.meta b/Assets/Scripts/Core/Fsr2Pass.cs.meta similarity index 100% rename from Assets/Scripts/Core/Fsr2Pipeline.cs.meta rename to Assets/Scripts/Core/Fsr2Pass.cs.meta diff --git a/Assets/Scripts/Fsr2ImageEffect.cs b/Assets/Scripts/Fsr2ImageEffect.cs index 7daeb60..e0f87d7 100644 --- a/Assets/Scripts/Fsr2ImageEffect.cs +++ b/Assets/Scripts/Fsr2ImageEffect.cs @@ -301,21 +301,20 @@ namespace FidelityFX private void SetupDispatchDescription() { // Set up the main FSR2 dispatch parameters - // The input and output textures are left blank here, as they get bound directly through SetGlobalTexture and GetTemporaryRT elsewhere in this source file - _dispatchDescription.Color = null; - _dispatchDescription.Depth = null; - _dispatchDescription.MotionVectors = null; - _dispatchDescription.Exposure = null; - _dispatchDescription.Reactive = null; - _dispatchDescription.TransparencyAndComposition = null; + _dispatchDescription.Color = new Fsr2.ResourceView(BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color); + _dispatchDescription.Depth = new Fsr2.ResourceView(BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth); + _dispatchDescription.MotionVectors = new Fsr2.ResourceView(BuiltinRenderTextureType.MotionVectors); + _dispatchDescription.Exposure = Fsr2.ResourceView.Unassigned; + _dispatchDescription.Reactive = Fsr2.ResourceView.Unassigned; + _dispatchDescription.TransparencyAndComposition = Fsr2.ResourceView.Unassigned; - if (!enableAutoExposure && exposure != null) _dispatchDescription.Exposure = exposure; - if (reactiveMask != null) _dispatchDescription.Reactive = reactiveMask; - if (transparencyAndCompositionMask != null) _dispatchDescription.TransparencyAndComposition = transparencyAndCompositionMask; + if (!enableAutoExposure && exposure != null) _dispatchDescription.Exposure = new Fsr2.ResourceView(exposure); + if (reactiveMask != null) _dispatchDescription.Reactive = new Fsr2.ResourceView(reactiveMask); + if (transparencyAndCompositionMask != null) _dispatchDescription.TransparencyAndComposition = new Fsr2.ResourceView(transparencyAndCompositionMask); var scaledRenderSize = GetScaledRenderSize(); - _dispatchDescription.Output = null; + _dispatchDescription.Output = new Fsr2.ResourceView(Fsr2ShaderIDs.UavUpscaledOutput); _dispatchDescription.PreExposure = preExposure; _dispatchDescription.EnableSharpening = performSharpenPass; _dispatchDescription.Sharpness = sharpness; @@ -334,7 +333,7 @@ namespace FidelityFX _dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition; if (autoGenerateTransparencyAndComposition) { - _dispatchDescription.ColorOpaqueOnly = _colorOpaqueOnly; + _dispatchDescription.ColorOpaqueOnly = new Fsr2.ResourceView(_colorOpaqueOnly); _dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold; _dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale; _dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale; @@ -351,9 +350,9 @@ namespace FidelityFX private void SetupAutoReactiveDescription() { // Set up the parameters to auto-generate a reactive mask - _genReactiveDescription.ColorOpaqueOnly = _colorOpaqueOnly; - _genReactiveDescription.ColorPreUpscale = null; - _genReactiveDescription.OutReactive = null; + _genReactiveDescription.ColorOpaqueOnly = new Fsr2.ResourceView(_colorOpaqueOnly); + _genReactiveDescription.ColorPreUpscale = new Fsr2.ResourceView(BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color); + _genReactiveDescription.OutReactive = new Fsr2.ResourceView(Fsr2ShaderIDs.UavAutoReactive); _genReactiveDescription.RenderSize = GetScaledRenderSize(); _genReactiveDescription.Scale = generateReactiveParameters.scale; _genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold; @@ -390,9 +389,6 @@ namespace FidelityFX _dispatchDescription.InputResourceSize = new Vector2Int(src.width, src.height); _dispatchCommandBuffer.Clear(); - _dispatchCommandBuffer.SetGlobalTexture(Fsr2ShaderIDs.SrvInputColor, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color); - _dispatchCommandBuffer.SetGlobalTexture(Fsr2ShaderIDs.SrvInputDepth, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth); - _dispatchCommandBuffer.SetGlobalTexture(Fsr2ShaderIDs.SrvInputMotionVectors, BuiltinRenderTextureType.MotionVectors); if (autoGenerateReactiveMask) { @@ -400,7 +396,7 @@ namespace FidelityFX var scaledRenderSize = GetScaledRenderSize(); _dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); _context.GenerateReactiveMask(_genReactiveDescription, _dispatchCommandBuffer); - _dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive; + _dispatchDescription.Reactive = new Fsr2.ResourceView(Fsr2ShaderIDs.UavAutoReactive); } // The backbuffer is not set up to allow random-write access, so we need a temporary render texture for FSR2 to output to diff --git a/com.unity.postprocessing/PostProcessing/Runtime/Effects/SuperResolution.cs b/com.unity.postprocessing/PostProcessing/Runtime/Effects/SuperResolution.cs index d87b99f..e7ff440 100644 --- a/com.unity.postprocessing/PostProcessing/Runtime/Effects/SuperResolution.cs +++ b/com.unity.postprocessing/PostProcessing/Runtime/Effects/SuperResolution.cs @@ -178,10 +178,6 @@ namespace UnityEngine.Rendering.PostProcessing CreateFsrContext(context); } - cmd.SetGlobalTexture(Fsr2ShaderIDs.SrvInputColor, context.source); - cmd.SetGlobalTexture(Fsr2ShaderIDs.SrvInputDepth, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth); - cmd.SetGlobalTexture(Fsr2ShaderIDs.SrvInputMotionVectors, BuiltinRenderTextureType.MotionVectors); - SetupDispatchDescription(context); if (autoGenerateReactiveMask) @@ -191,7 +187,7 @@ namespace UnityEngine.Rendering.PostProcessing var scaledRenderSize = _genReactiveDescription.RenderSize; cmd.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); _fsrContext.GenerateReactiveMask(_genReactiveDescription, cmd); - _dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive; + _dispatchDescription.Reactive = new Fsr2.ResourceView(Fsr2ShaderIDs.UavAutoReactive); } _fsrContext.Dispatch(_dispatchDescription, cmd); @@ -267,22 +263,21 @@ namespace UnityEngine.Rendering.PostProcessing var camera = context.camera; // Set up the main FSR2 dispatch parameters - // The input textures are left blank here, as they get bound directly through SetGlobalTexture elsewhere in this source file - _dispatchDescription.Color = null; - _dispatchDescription.Depth = null; - _dispatchDescription.MotionVectors = null; - _dispatchDescription.Exposure = null; - _dispatchDescription.Reactive = null; - _dispatchDescription.TransparencyAndComposition = null; - - if (exposureSource == ExposureSource.Manual && exposure != null) _dispatchDescription.Exposure = exposure; - if (exposureSource == ExposureSource.Unity) _dispatchDescription.Exposure = context.autoExposureTexture; - if (reactiveMask != null) _dispatchDescription.Reactive = reactiveMask; - if (transparencyAndCompositionMask != null) _dispatchDescription.TransparencyAndComposition = transparencyAndCompositionMask; + _dispatchDescription.Color = new Fsr2.ResourceView(context.source); + _dispatchDescription.Depth = new Fsr2.ResourceView(BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth); + _dispatchDescription.MotionVectors = new Fsr2.ResourceView(BuiltinRenderTextureType.MotionVectors); + _dispatchDescription.Exposure = Fsr2.ResourceView.Unassigned; + _dispatchDescription.Reactive = Fsr2.ResourceView.Unassigned; + _dispatchDescription.TransparencyAndComposition = Fsr2.ResourceView.Unassigned; + + if (exposureSource == ExposureSource.Manual && exposure != null) _dispatchDescription.Exposure = new Fsr2.ResourceView(exposure); + if (exposureSource == ExposureSource.Unity) _dispatchDescription.Exposure = new Fsr2.ResourceView(context.autoExposureTexture); + if (reactiveMask != null) _dispatchDescription.Reactive = new Fsr2.ResourceView(reactiveMask); + if (transparencyAndCompositionMask != null) _dispatchDescription.TransparencyAndComposition = new Fsr2.ResourceView(transparencyAndCompositionMask); var scaledRenderSize = GetScaledRenderSize(context.camera); - _dispatchDescription.Output = context.destination; + _dispatchDescription.Output = new Fsr2.ResourceView(context.destination); _dispatchDescription.PreExposure = preExposure; _dispatchDescription.EnableSharpening = performSharpenPass; _dispatchDescription.Sharpness = sharpness; @@ -301,7 +296,7 @@ namespace UnityEngine.Rendering.PostProcessing _dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition; if (autoGenerateTransparencyAndComposition) { - _dispatchDescription.ColorOpaqueOnly = colorOpaqueOnly; + _dispatchDescription.ColorOpaqueOnly = new Fsr2.ResourceView(colorOpaqueOnly); _dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold; _dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale; _dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale; @@ -318,9 +313,9 @@ namespace UnityEngine.Rendering.PostProcessing private void SetupAutoReactiveDescription(PostProcessRenderContext context) { // Set up the parameters to auto-generate a reactive mask - _genReactiveDescription.ColorOpaqueOnly = colorOpaqueOnly; - _genReactiveDescription.ColorPreUpscale = null; - _genReactiveDescription.OutReactive = null; + _genReactiveDescription.ColorOpaqueOnly = new Fsr2.ResourceView(colorOpaqueOnly); + _genReactiveDescription.ColorPreUpscale = new Fsr2.ResourceView(context.source); + _genReactiveDescription.OutReactive = new Fsr2.ResourceView(Fsr2ShaderIDs.UavAutoReactive); _genReactiveDescription.RenderSize = GetScaledRenderSize(context.camera); _genReactiveDescription.Scale = generateReactiveParameters.scale; _genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold; diff --git a/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2.cs b/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2.cs index 772cfc3..1ba8192 100644 --- a/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2.cs +++ b/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2.cs @@ -125,6 +125,13 @@ namespace FidelityFX return Mathf.Abs(value) < Mathf.Epsilon ? 1.0f : Mathf.Sin(Mathf.PI * value) / (Mathf.PI * value) * (Mathf.Sin(0.5f * Mathf.PI * value) / (0.5f * Mathf.PI * value)); } +#if !UNITY_2021_1_OR_NEWER + internal static void SetBufferData(this CommandBuffer commandBuffer, ComputeBuffer computeBuffer, Array data) + { + commandBuffer.SetComputeBufferData(computeBuffer, data); + } +#endif + public enum QualityMode { UltraQuality = 0, @@ -155,20 +162,50 @@ namespace FidelityFX public Vector2Int DisplaySize; public IFsr2Callbacks Callbacks; } + + /// + /// An immutable structure wrapping all of the necessary information to bind a specific buffer or attachment of a render target to a compute shader. + /// + public readonly struct ResourceView + { + /// + /// This value is the equivalent of not setting any value at all; all struct fields will have their default values. + /// It does not refer to a valid texture, therefore any variable set to this value should be checked for IsValid and reassigned before being bound to a shader. + /// + public static readonly ResourceView Unassigned = new ResourceView(default); + + /// + /// This value contains a valid texture reference that can be bound to a shader, however it is just an empty placeholder texture. + /// Binding this to a shader can be seen as setting the texture variable inside the shader to null. + /// + public static readonly ResourceView None = new ResourceView(BuiltinRenderTextureType.None); + + public ResourceView(in RenderTargetIdentifier renderTarget, RenderTextureSubElement subElement = RenderTextureSubElement.Default, int mipLevel = 0) + { + RenderTarget = renderTarget; + SubElement = subElement; + MipLevel = mipLevel; + } + + public bool IsValid => !RenderTarget.Equals(default); + + public readonly RenderTargetIdentifier RenderTarget; + public readonly RenderTextureSubElement SubElement; + public readonly int MipLevel; + } /// - /// The input and output resources are all optional. If they are null, the Fsr2Context won't try to bind them to any shaders. - /// This allows for customized and more efficient resource management outside of Fsr2Context, tailored to the specific scenario. + /// A structure encapsulating the parameters for dispatching the various passes of FidelityFX Super Resolution 2. /// public class DispatchDescription { - public RenderTargetIdentifier? Color; - public RenderTargetIdentifier? Depth; - public RenderTargetIdentifier? MotionVectors; - public RenderTargetIdentifier? Exposure; - public RenderTargetIdentifier? Reactive; - public RenderTargetIdentifier? TransparencyAndComposition; - public RenderTargetIdentifier? Output; + public ResourceView Color; + public ResourceView Depth; + public ResourceView MotionVectors; + public ResourceView Exposure; // optional + public ResourceView Reactive; // optional + public ResourceView TransparencyAndComposition; // optional + public ResourceView Output; public Vector2 JitterOffset; public Vector2 MotionVectorScale; public Vector2Int RenderSize; @@ -185,7 +222,7 @@ namespace FidelityFX // EXPERIMENTAL reactive mask generation parameters public bool EnableAutoReactive; - public RenderTargetIdentifier? ColorOpaqueOnly; + public ResourceView ColorOpaqueOnly; public float AutoTcThreshold = 0.05f; public float AutoTcScale = 1.0f; public float AutoReactiveScale = 5.0f; @@ -193,13 +230,14 @@ namespace FidelityFX } /// + /// A structure encapsulating the parameters for automatic generation of a reactive mask. /// The default values for Scale, CutoffThreshold, BinaryValue and Flags were taken from the FSR2 demo project. /// public class GenerateReactiveDescription { - public RenderTargetIdentifier? ColorOpaqueOnly; - public RenderTargetIdentifier? ColorPreUpscale; - public RenderTargetIdentifier? OutReactive; + public ResourceView ColorOpaqueOnly; + public ResourceView ColorPreUpscale; + public ResourceView OutReactive; public Vector2Int RenderSize; public float Scale = 0.5f; public float CutoffThreshold = 0.2f; diff --git a/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Context.cs b/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Context.cs index b1d9a17..5c8975c 100644 --- a/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Context.cs +++ b/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Context.cs @@ -39,14 +39,14 @@ namespace FidelityFX private Fsr2.ContextDescription _contextDescription; private CommandBuffer _commandBuffer; - private Fsr2Pipeline _depthClipPipeline; - private Fsr2Pipeline _reconstructPreviousDepthPipeline; - private Fsr2Pipeline _lockPipeline; - private Fsr2Pipeline _accumulatePipeline; - private Fsr2Pipeline _rcasPipeline; - private Fsr2Pipeline _computeLuminancePyramidPipeline; - private Fsr2Pipeline _generateReactivePipeline; - private Fsr2Pipeline _tcrAutogeneratePipeline; + private Fsr2Pass _depthClipPass; + private Fsr2Pass _reconstructPreviousDepthPass; + private Fsr2Pass _lockPass; + private Fsr2Pass _accumulatePass; + private Fsr2Pass _rcasPass; + private Fsr2Pass _computeLuminancePyramidPass; + private Fsr2Pass _generateReactivePass; + private Fsr2Pass _tcrAutogeneratePass; private readonly Fsr2Resources _resources = new Fsr2Resources(); @@ -92,31 +92,31 @@ namespace FidelityFX Constants.displaySize = _contextDescription.DisplaySize; _resources.Create(_contextDescription); - CreatePipelines(); + CreatePasses(); } - private void CreatePipelines() + private void CreatePasses() { - _computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer, _spdConstantsBuffer); - _reconstructPreviousDepthPipeline = new Fsr2ReconstructPreviousDepthPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _depthClipPipeline = new Fsr2DepthClipPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _lockPipeline = new Fsr2LockPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _accumulatePipeline = new Fsr2AccumulatePipeline(_contextDescription, _resources, _fsr2ConstantsBuffer); - _rcasPipeline = new Fsr2RcasPipeline(_contextDescription, _resources, _fsr2ConstantsBuffer, _rcasConstantsBuffer); - _generateReactivePipeline = new Fsr2GenerateReactivePipeline(_contextDescription, _resources, _generateReactiveConstantsBuffer); - _tcrAutogeneratePipeline = new Fsr2TcrAutogeneratePipeline(_contextDescription, _resources, _fsr2ConstantsBuffer, _tcrAutogenerateConstantsBuffer); + _computeLuminancePyramidPass = new Fsr2ComputeLuminancePyramidPass(_contextDescription, _resources, _fsr2ConstantsBuffer, _spdConstantsBuffer); + _reconstructPreviousDepthPass = new Fsr2ReconstructPreviousDepthPass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _depthClipPass = new Fsr2DepthClipPass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _lockPass = new Fsr2LockPass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _accumulatePass = new Fsr2AccumulatePass(_contextDescription, _resources, _fsr2ConstantsBuffer); + _rcasPass = new Fsr2RcasPass(_contextDescription, _resources, _fsr2ConstantsBuffer, _rcasConstantsBuffer); + _generateReactivePass = new Fsr2GenerateReactivePass(_contextDescription, _resources, _generateReactiveConstantsBuffer); + _tcrAutogeneratePass = new Fsr2TcrAutogeneratePass(_contextDescription, _resources, _fsr2ConstantsBuffer, _tcrAutogenerateConstantsBuffer); } public void Destroy() { - DestroyPipeline(ref _tcrAutogeneratePipeline); - DestroyPipeline(ref _generateReactivePipeline); - DestroyPipeline(ref _computeLuminancePyramidPipeline); - DestroyPipeline(ref _rcasPipeline); - DestroyPipeline(ref _accumulatePipeline); - DestroyPipeline(ref _lockPipeline); - DestroyPipeline(ref _reconstructPreviousDepthPipeline); - DestroyPipeline(ref _depthClipPipeline); + DestroyPass(ref _tcrAutogeneratePass); + DestroyPass(ref _generateReactivePass); + DestroyPass(ref _computeLuminancePyramidPass); + DestroyPass(ref _rcasPass); + DestroyPass(ref _accumulatePass); + DestroyPass(ref _lockPass); + DestroyPass(ref _reconstructPreviousDepthPass); + DestroyPass(ref _depthClipPass); _resources.Destroy(); @@ -158,18 +158,21 @@ namespace FidelityFX // If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends if ((_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) - dispatchParams.Exposure = _resources.AutoExposure; - else if (dispatchParams.Exposure == null) - dispatchParams.Exposure = _resources.DefaultExposure; + dispatchParams.Exposure = new Fsr2.ResourceView(_resources.AutoExposure); + else if (!dispatchParams.Exposure.IsValid) + dispatchParams.Exposure = new Fsr2.ResourceView(_resources.DefaultExposure); if (dispatchParams.EnableAutoReactive) { // Create the auto-TCR resources only when we need them if (_resources.AutoReactive == null) _resources.CreateTcrAutogenResources(_contextDescription); - + if (resetAccumulation) - commandBuffer.Blit(_resources.PrevPreAlpha[frameIndex ^ 1], dispatchParams.ColorOpaqueOnly ?? Fsr2ShaderIDs.SrvOpaqueOnly); + { + RenderTargetIdentifier opaqueOnly = dispatchParams.ColorOpaqueOnly.IsValid ? dispatchParams.ColorOpaqueOnly.RenderTarget : Fsr2ShaderIDs.SrvOpaqueOnly; + commandBuffer.Blit(_resources.PrevPreAlpha[frameIndex ^ 1], opaqueOnly); + } } else if (_resources.AutoReactive != null) { @@ -177,8 +180,8 @@ namespace FidelityFX _resources.DestroyTcrAutogenResources(); } - if (dispatchParams.Reactive == null) dispatchParams.Reactive = _resources.DefaultReactive; - if (dispatchParams.TransparencyAndComposition == null) dispatchParams.TransparencyAndComposition = _resources.DefaultReactive; + if (!dispatchParams.Reactive.IsValid) dispatchParams.Reactive = new Fsr2.ResourceView(_resources.DefaultReactive); + if (!dispatchParams.TransparencyAndComposition.IsValid) dispatchParams.TransparencyAndComposition = new Fsr2.ResourceView(_resources.DefaultReactive); Fsr2Resources.CreateAliasableResources(commandBuffer, _contextDescription, dispatchParams); SetupConstants(dispatchParams, resetAccumulation); @@ -222,24 +225,24 @@ namespace FidelityFX if (dispatchParams.EnableAutoReactive) { GenerateTransparencyCompositionReactive(dispatchParams, commandBuffer, frameIndex); - dispatchParams.Reactive = _resources.AutoReactive; - dispatchParams.TransparencyAndComposition = _resources.AutoComposition; + dispatchParams.Reactive = new Fsr2.ResourceView(_resources.AutoReactive); + dispatchParams.TransparencyAndComposition = new Fsr2.ResourceView(_resources.AutoComposition); } // Compute luminance pyramid - _computeLuminancePyramidPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); + _computeLuminancePyramidPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); // Reconstruct previous depth - _reconstructPreviousDepthPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _reconstructPreviousDepthPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Depth clip - _depthClipPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _depthClipPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Create locks - _lockPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _lockPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); // Accumulate - _accumulatePipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY); + _accumulatePass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY); if (dispatchParams.EnableSharpening) { @@ -251,7 +254,7 @@ namespace FidelityFX const int threadGroupWorkRegionDimRcas = 16; int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; - _rcasPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY); + _rcasPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY); } _resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames; @@ -278,7 +281,7 @@ namespace FidelityFX GenReactiveConsts.flags = (uint)dispatchParams.Flags; commandBuffer.SetBufferData(_generateReactiveConstantsBuffer, _generateReactiveConstantsArray); - ((Fsr2GenerateReactivePipeline)_generateReactivePipeline).ScheduleDispatch(commandBuffer, dispatchParams, dispatchSrcX, dispatchSrcY); + ((Fsr2GenerateReactivePass)_generateReactivePass).ScheduleDispatch(commandBuffer, dispatchParams, dispatchSrcX, dispatchSrcY); } private void GenerateTransparencyCompositionReactive(Fsr2.DispatchDescription dispatchParams, CommandBuffer commandBuffer, int frameIndex) @@ -293,7 +296,7 @@ namespace FidelityFX TcrAutoGenConsts.autoReactiveMax = dispatchParams.AutoReactiveMax; commandBuffer.SetBufferData(_tcrAutogenerateConstantsBuffer, _tcrAutogenerateConstantsArray); - _tcrAutogeneratePipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); + _tcrAutogeneratePass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY); } private void SetupConstants(Fsr2.DispatchDescription dispatchParams, bool resetAccumulation) @@ -353,7 +356,7 @@ namespace FidelityFX constants.frameIndex++; // Shading change usage of the SPD mip levels - constants.lumaMipLevelToUse = Fsr2Pipeline.ShadingChangeMipLevel; + constants.lumaMipLevelToUse = Fsr2Pass.ShadingChangeMipLevel; float mipDiv = 2 << constants.lumaMipLevelToUse; constants.lumaMipDimensions.x = (int)(constants.maxRenderSize.x / mipDiv); @@ -395,7 +398,7 @@ namespace FidelityFX private void SetupRcasConstants(Fsr2.DispatchDescription dispatchParams) { - int sharpnessIndex = Mathf.RoundToInt(Mathf.Clamp01(dispatchParams.Sharpness) * (RcasConfigs.Count - 1)); + int sharpnessIndex = Mathf.RoundToInt(Mathf.Clamp01(dispatchParams.Sharpness) * (RcasConfigs.Length - 1)); RcasConsts = RcasConfigs[sharpnessIndex]; } @@ -433,31 +436,27 @@ namespace FidelityFX private void DebugCheckDispatch(Fsr2.DispatchDescription dispatchParams) { - // Global texture binding may be queued as part of the command list, which is why we check these after running the process at least once - if (!_firstExecution && !dispatchParams.Reset) + if (!dispatchParams.Color.IsValid) { - if (!dispatchParams.Color.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputColor) == null) - { - Debug.LogError("Color resource is null"); - } - - if (!dispatchParams.Depth.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputDepth) == null) - { - Debug.LogError("Depth resource is null"); - } - - if (!dispatchParams.MotionVectors.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputMotionVectors) == null) - { - Debug.LogError("MotionVectors resource is null"); - } - - if (!dispatchParams.Output.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.UavUpscaledOutput) == null) - { - Debug.LogError("Output resource is null"); - } + Debug.LogError("Color resource is null"); } - - if (dispatchParams.Exposure.HasValue && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) + + if (!dispatchParams.Depth.IsValid) + { + Debug.LogError("Depth resource is null"); + } + + if (!dispatchParams.MotionVectors.IsValid) + { + Debug.LogError("MotionVectors resource is null"); + } + + if (!dispatchParams.Output.IsValid) + { + Debug.LogError("Output resource is null"); + } + + if (dispatchParams.Exposure.IsValid && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) { Debug.LogWarning("Exposure resource provided, however auto exposure flag is present"); } @@ -556,7 +555,7 @@ namespace FidelityFX /// The FSR2 C++ codebase uses floats bitwise converted to ints to pass sharpness parameters to the RCAS shader. /// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values. /// - private static readonly List RcasConfigs = new List() + private static readonly Fsr2.RcasConstants[] RcasConfigs = new [] { new Fsr2.RcasConstants(1048576000u, 872428544u), new Fsr2.RcasConstants(1049178080u, 877212745u), @@ -595,13 +594,13 @@ namespace FidelityFX bufferRef = null; } - private static void DestroyPipeline(ref Fsr2Pipeline pipeline) + private static void DestroyPass(ref Fsr2Pass pass) { - if (pipeline == null) + if (pass == null) return; - pipeline.Dispose(); - pipeline = null; + pass.Dispose(); + pass = null; } } } diff --git a/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pipeline.cs b/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs similarity index 69% rename from com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pipeline.cs rename to com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs index 5b963f0..23b8e6c 100644 --- a/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pipeline.cs +++ b/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs @@ -30,7 +30,7 @@ namespace FidelityFX /// This loosely matches the FfxPipelineState struct from the original FSR2 codebase, wrapped in an object-oriented blanket. /// These classes are responsible for loading compute shaders, managing temporary resources, binding resources to shader kernels and dispatching said shaders. /// - internal abstract class Fsr2Pipeline: IDisposable + internal abstract class Fsr2Pass: IDisposable { internal const int ShadingChangeMipLevel = 4; // This matches the FFX_FSR2_SHADING_CHANGE_MIP_LEVEL define @@ -43,7 +43,7 @@ namespace FidelityFX protected virtual bool AllowFP16 => true; - protected Fsr2Pipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + protected Fsr2Pass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) { ContextDescription = contextDescription; Resources = resources; @@ -115,11 +115,11 @@ namespace FidelityFX } } - internal class Fsr2ComputeLuminancePyramidPipeline : Fsr2Pipeline + internal class Fsr2ComputeLuminancePyramidPass : Fsr2Pass { private readonly ComputeBuffer _spdConstants; - public Fsr2ComputeLuminancePyramidPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer spdConstants) + public Fsr2ComputeLuminancePyramidPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer spdConstants) : base(contextDescription, resources, constants) { _spdConstants = spdConstants; @@ -129,8 +129,8 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); + ref var color = ref dispatchParams.Color; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavSpdAtomicCount, Resources.SpdAtomicCounter); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel); @@ -144,9 +144,9 @@ namespace FidelityFX } } - internal class Fsr2ReconstructPreviousDepthPipeline : Fsr2Pipeline + internal class Fsr2ReconstructPreviousDepthPass : Fsr2Pass { - public Fsr2ReconstructPreviousDepthPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2ReconstructPreviousDepthPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass"); @@ -154,18 +154,16 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.Depth.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, dispatchParams.Depth.Value, 0, RenderTextureSubElement.Depth); - - if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); + ref var color = ref dispatchParams.Color; + ref var depth = ref dispatchParams.Depth; + ref var motionVectors = ref dispatchParams.MotionVectors; + ref var exposure = ref dispatchParams.Exposure; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf()); @@ -174,9 +172,9 @@ namespace FidelityFX } } - internal class Fsr2DepthClipPipeline : Fsr2Pipeline + internal class Fsr2DepthClipPass : Fsr2Pass { - public Fsr2DepthClipPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2DepthClipPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass"); @@ -184,24 +182,20 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.Depth.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, dispatchParams.Depth.Value, 0, RenderTextureSubElement.Depth); - - if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); + ref var color = ref dispatchParams.Color; + ref var depth = ref dispatchParams.Depth; + ref var motionVectors = ref dispatchParams.MotionVectors; + ref var exposure = ref dispatchParams.Exposure; + ref var reactive = ref dispatchParams.Reactive; + ref var tac = ref dispatchParams.TransparencyAndComposition; + + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, tac.RenderTarget, tac.MipLevel, tac.SubElement); - if (dispatchParams.Reactive.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, dispatchParams.Reactive.Value); - - if (dispatchParams.TransparencyAndComposition.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, dispatchParams.TransparencyAndComposition.Value); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReconstructedPrevNearestDepth, Fsr2ShaderIDs.UavReconstructedPrevNearestDepth); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedDepth, Fsr2ShaderIDs.UavDilatedDepth); @@ -213,9 +207,9 @@ namespace FidelityFX } } - internal class Fsr2LockPipeline : Fsr2Pipeline + internal class Fsr2LockPass : Fsr2Pass { - public Fsr2LockPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2LockPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_lock_pass"); @@ -230,7 +224,7 @@ namespace FidelityFX } } - internal class Fsr2AccumulatePipeline : Fsr2Pipeline + internal class Fsr2AccumulatePass : Fsr2Pass { private const string SharpeningKeyword = "FFX_FSR2_OPTION_APPLY_SHARPENING"; @@ -241,7 +235,7 @@ namespace FidelityFX private readonly LocalKeyword _sharpeningKeyword; #endif - public Fsr2AccumulatePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) + public Fsr2AccumulatePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass"); @@ -265,13 +259,18 @@ namespace FidelityFX #endif if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) + { commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); - else if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); - + } + else + { + ref var motionVectors = ref dispatchParams.MotionVectors; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); + } + + ref var exposure = ref dispatchParams.Exposure; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedReactiveMasks, Fsr2ShaderIDs.UavDilatedReactiveMasks); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvLockStatus, Resources.LockStatus[frameIndex ^ 1]); @@ -286,8 +285,8 @@ namespace FidelityFX commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLumaHistory, Resources.LumaHistory[frameIndex]); - if (dispatchParams.Output.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, dispatchParams.Output.Value); + ref var output = ref dispatchParams.Output; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf()); @@ -295,11 +294,11 @@ namespace FidelityFX } } - internal class Fsr2RcasPipeline : Fsr2Pipeline + internal class Fsr2RcasPass : Fsr2Pass { private readonly ComputeBuffer _rcasConstants; - public Fsr2RcasPipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer rcasConstants) + public Fsr2RcasPass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer rcasConstants) : base(contextDescription, resources, constants) { _rcasConstants = rcasConstants; @@ -309,13 +308,12 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.Exposure.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, dispatchParams.Exposure.Value); - + ref var exposure = ref dispatchParams.Exposure; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvRcasInput, Resources.InternalUpscaled[frameIndex]); - if (dispatchParams.Output.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, dispatchParams.Output.Value); + ref var output = ref dispatchParams.Output; + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbRcas, _rcasConstants, 0, Marshal.SizeOf()); @@ -324,11 +322,11 @@ namespace FidelityFX } } - internal class Fsr2GenerateReactivePipeline : Fsr2Pipeline + internal class Fsr2GenerateReactivePass : Fsr2Pass { private readonly ComputeBuffer _generateReactiveConstants; - public Fsr2GenerateReactivePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer generateReactiveConstants) + public Fsr2GenerateReactivePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer generateReactiveConstants) : base(contextDescription, resources, null) { _generateReactiveConstants = generateReactiveConstants; @@ -342,14 +340,13 @@ namespace FidelityFX public void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.GenerateReactiveDescription dispatchParams, int dispatchX, int dispatchY) { - if (dispatchParams.ColorOpaqueOnly.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, dispatchParams.ColorOpaqueOnly.Value, 0, RenderTextureSubElement.Color); + ref var opaqueOnly = ref dispatchParams.ColorOpaqueOnly; + ref var color = ref dispatchParams.ColorPreUpscale; + ref var reactive = ref dispatchParams.OutReactive; - if (dispatchParams.ColorPreUpscale.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.ColorPreUpscale.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.OutReactive.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoReactive, dispatchParams.OutReactive.Value); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, opaqueOnly.RenderTarget, opaqueOnly.MipLevel, opaqueOnly.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoReactive, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbGenReactive, _generateReactiveConstants, 0, Marshal.SizeOf()); @@ -357,11 +354,11 @@ namespace FidelityFX } } - internal class Fsr2TcrAutogeneratePipeline : Fsr2Pipeline + internal class Fsr2TcrAutogeneratePass : Fsr2Pass { private readonly ComputeBuffer _tcrAutogenerateConstants; - public Fsr2TcrAutogeneratePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer tcrAutogenerateConstants) + public Fsr2TcrAutogeneratePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants, ComputeBuffer tcrAutogenerateConstants) : base(contextDescription, resources, constants) { _tcrAutogenerateConstants = tcrAutogenerateConstants; @@ -371,23 +368,19 @@ namespace FidelityFX public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - if (dispatchParams.ColorOpaqueOnly.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, dispatchParams.ColorOpaqueOnly.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.Color.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, dispatchParams.Color.Value, 0, RenderTextureSubElement.Color); - - if (dispatchParams.MotionVectors.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value); - + ref var color = ref dispatchParams.Color; + ref var motionVectors = ref dispatchParams.MotionVectors; + ref var opaqueOnly = ref dispatchParams.ColorOpaqueOnly; + ref var reactive = ref dispatchParams.Reactive; + ref var tac = ref dispatchParams.TransparencyAndComposition; + + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, opaqueOnly.RenderTarget, opaqueOnly.MipLevel, opaqueOnly.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvPrevColorPreAlpha, Resources.PrevPreAlpha[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvPrevColorPostAlpha, Resources.PrevPostAlpha[frameIndex ^ 1]); - - if (dispatchParams.Reactive.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, dispatchParams.Reactive.Value); - - if (dispatchParams.TransparencyAndComposition.HasValue) - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, dispatchParams.TransparencyAndComposition.Value); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReactiveMask, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvTransparencyAndCompositionMask, tac.RenderTarget, tac.MipLevel, tac.SubElement); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoReactive, Resources.AutoReactive); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoComposition, Resources.AutoComposition); diff --git a/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pipeline.cs.meta b/com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs.meta similarity index 100% rename from com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pipeline.cs.meta rename to com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs.meta