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