Browse Source

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.
hdrp ppv2-3.3.1d
Nico de Poel 2 years ago
parent
commit
982c41cc20
  1. 57
      Assets/Scripts/Core/Fsr2.cs
  2. 135
      Assets/Scripts/Core/Fsr2Context.cs
  3. 153
      Assets/Scripts/Core/Fsr2Pass.cs
  4. 0
      Assets/Scripts/Core/Fsr2Pass.cs.meta
  5. 36
      Assets/Scripts/Fsr2ImageEffect.cs
  6. 39
      com.unity.postprocessing/PostProcessing/Runtime/Effects/SuperResolution.cs
  7. 64
      com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2.cs
  8. 135
      com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Context.cs
  9. 153
      com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs
  10. 0
      com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs.meta

57
Assets/Scripts/Core/Fsr2.cs

@ -164,18 +164,48 @@ namespace FidelityFX
} }
/// <summary> /// <summary>
/// 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.
/// An immutable structure wrapping all of the necessary information to bind a specific buffer or attachment of a render target to a compute shader.
/// </summary>
public readonly struct ResourceView
{
/// <summary>
/// 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.
/// </summary>
public static readonly ResourceView Unassigned = new ResourceView(default);
/// <summary>
/// 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.
/// </summary>
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;
}
/// <summary>
/// A structure encapsulating the parameters for dispatching the various passes of FidelityFX Super Resolution 2.
/// </summary> /// </summary>
public class DispatchDescription 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 JitterOffset;
public Vector2 MotionVectorScale; public Vector2 MotionVectorScale;
public Vector2Int RenderSize; public Vector2Int RenderSize;
@ -192,7 +222,7 @@ namespace FidelityFX
// EXPERIMENTAL reactive mask generation parameters // EXPERIMENTAL reactive mask generation parameters
public bool EnableAutoReactive; public bool EnableAutoReactive;
public RenderTargetIdentifier? ColorOpaqueOnly;
public ResourceView ColorOpaqueOnly;
public float AutoTcThreshold = 0.05f; public float AutoTcThreshold = 0.05f;
public float AutoTcScale = 1.0f; public float AutoTcScale = 1.0f;
public float AutoReactiveScale = 5.0f; public float AutoReactiveScale = 5.0f;
@ -200,13 +230,14 @@ namespace FidelityFX
} }
/// <summary> /// <summary>
/// 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. /// The default values for Scale, CutoffThreshold, BinaryValue and Flags were taken from the FSR2 demo project.
/// </summary> /// </summary>
public class GenerateReactiveDescription 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 Vector2Int RenderSize;
public float Scale = 0.5f; public float Scale = 0.5f;
public float CutoffThreshold = 0.2f; public float CutoffThreshold = 0.2f;

135
Assets/Scripts/Core/Fsr2Context.cs

@ -39,14 +39,14 @@ namespace FidelityFX
private Fsr2.ContextDescription _contextDescription; private Fsr2.ContextDescription _contextDescription;
private CommandBuffer _commandBuffer; 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(); private readonly Fsr2Resources _resources = new Fsr2Resources();
@ -92,31 +92,31 @@ namespace FidelityFX
Constants.displaySize = _contextDescription.DisplaySize; Constants.displaySize = _contextDescription.DisplaySize;
_resources.Create(_contextDescription); _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() 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(); _resources.Destroy();
@ -158,9 +158,9 @@ namespace FidelityFX
// If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends // If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends
if ((_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) 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) if (dispatchParams.EnableAutoReactive)
{ {
@ -169,7 +169,10 @@ namespace FidelityFX
_resources.CreateTcrAutogenResources(_contextDescription); _resources.CreateTcrAutogenResources(_contextDescription);
if (resetAccumulation) 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) else if (_resources.AutoReactive != null)
{ {
@ -177,8 +180,8 @@ namespace FidelityFX
_resources.DestroyTcrAutogenResources(); _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); Fsr2Resources.CreateAliasableResources(commandBuffer, _contextDescription, dispatchParams);
SetupConstants(dispatchParams, resetAccumulation); SetupConstants(dispatchParams, resetAccumulation);
@ -222,24 +225,24 @@ namespace FidelityFX
if (dispatchParams.EnableAutoReactive) if (dispatchParams.EnableAutoReactive)
{ {
GenerateTransparencyCompositionReactive(dispatchParams, commandBuffer, frameIndex); 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 // Compute luminance pyramid
_computeLuminancePyramidPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y);
_computeLuminancePyramidPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y);
// Reconstruct previous depth // Reconstruct previous depth
_reconstructPreviousDepthPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
_reconstructPreviousDepthPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
// Depth clip // Depth clip
_depthClipPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
_depthClipPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
// Create locks // Create locks
_lockPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
_lockPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
// Accumulate // Accumulate
_accumulatePipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY);
_accumulatePass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY);
if (dispatchParams.EnableSharpening) if (dispatchParams.EnableSharpening)
{ {
@ -251,7 +254,7 @@ namespace FidelityFX
const int threadGroupWorkRegionDimRcas = 16; const int threadGroupWorkRegionDimRcas = 16;
int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
int threadGroupsY = (Screen.height + 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; _resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames;
@ -278,7 +281,7 @@ namespace FidelityFX
GenReactiveConsts.flags = (uint)dispatchParams.Flags; GenReactiveConsts.flags = (uint)dispatchParams.Flags;
commandBuffer.SetBufferData(_generateReactiveConstantsBuffer, _generateReactiveConstantsArray); 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) private void GenerateTransparencyCompositionReactive(Fsr2.DispatchDescription dispatchParams, CommandBuffer commandBuffer, int frameIndex)
@ -293,7 +296,7 @@ namespace FidelityFX
TcrAutoGenConsts.autoReactiveMax = dispatchParams.AutoReactiveMax; TcrAutoGenConsts.autoReactiveMax = dispatchParams.AutoReactiveMax;
commandBuffer.SetBufferData(_tcrAutogenerateConstantsBuffer, _tcrAutogenerateConstantsArray); 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) private void SetupConstants(Fsr2.DispatchDescription dispatchParams, bool resetAccumulation)
@ -353,7 +356,7 @@ namespace FidelityFX
constants.frameIndex++; constants.frameIndex++;
// Shading change usage of the SPD mip levels // Shading change usage of the SPD mip levels
constants.lumaMipLevelToUse = Fsr2Pipeline.ShadingChangeMipLevel;
constants.lumaMipLevelToUse = Fsr2Pass.ShadingChangeMipLevel;
float mipDiv = 2 << constants.lumaMipLevelToUse; float mipDiv = 2 << constants.lumaMipLevelToUse;
constants.lumaMipDimensions.x = (int)(constants.maxRenderSize.x / mipDiv); constants.lumaMipDimensions.x = (int)(constants.maxRenderSize.x / mipDiv);
@ -395,7 +398,7 @@ namespace FidelityFX
private void SetupRcasConstants(Fsr2.DispatchDescription dispatchParams) 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]; RcasConsts = RcasConfigs[sharpnessIndex];
} }
@ -433,31 +436,27 @@ namespace FidelityFX
private void DebugCheckDispatch(Fsr2.DispatchDescription dispatchParams) 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");
}
Debug.LogError("Color resource is null");
}
if (!dispatchParams.Depth.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputDepth) == null)
{
Debug.LogError("Depth resource is null");
}
if (!dispatchParams.Depth.IsValid)
{
Debug.LogError("Depth resource is null");
}
if (!dispatchParams.MotionVectors.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputMotionVectors) == null)
{
Debug.LogError("MotionVectors resource is null");
}
if (!dispatchParams.MotionVectors.IsValid)
{
Debug.LogError("MotionVectors resource is null");
}
if (!dispatchParams.Output.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.UavUpscaledOutput) == null)
{
Debug.LogError("Output resource is null");
}
if (!dispatchParams.Output.IsValid)
{
Debug.LogError("Output resource is null");
} }
if (dispatchParams.Exposure.HasValue && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0)
if (dispatchParams.Exposure.IsValid && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0)
{ {
Debug.LogWarning("Exposure resource provided, however auto exposure flag is present"); 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. /// 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. /// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values.
/// </summary> /// </summary>
private static readonly List<Fsr2.RcasConstants> RcasConfigs = new List<Fsr2.RcasConstants>()
private static readonly Fsr2.RcasConstants[] RcasConfigs = new []
{ {
new Fsr2.RcasConstants(1048576000u, 872428544u), new Fsr2.RcasConstants(1048576000u, 872428544u),
new Fsr2.RcasConstants(1049178080u, 877212745u), new Fsr2.RcasConstants(1049178080u, 877212745u),
@ -595,13 +594,13 @@ namespace FidelityFX
bufferRef = null; bufferRef = null;
} }
private static void DestroyPipeline(ref Fsr2Pipeline pipeline)
private static void DestroyPass(ref Fsr2Pass pass)
{ {
if (pipeline == null)
if (pass == null)
return; return;
pipeline.Dispose();
pipeline = null;
pass.Dispose();
pass = null;
} }
} }
} }

153
Assets/Scripts/Core/Fsr2Pipeline.cs → 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. /// 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. /// These classes are responsible for loading compute shaders, managing temporary resources, binding resources to shader kernels and dispatching said shaders.
/// </summary> /// </summary>
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 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 virtual bool AllowFP16 => true;
protected Fsr2Pipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
protected Fsr2Pass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
{ {
ContextDescription = contextDescription; ContextDescription = contextDescription;
Resources = resources; Resources = resources;
@ -115,11 +115,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2ComputeLuminancePyramidPipeline : Fsr2Pipeline
internal class Fsr2ComputeLuminancePyramidPass : Fsr2Pass
{ {
private readonly ComputeBuffer _spdConstants; 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) : base(contextDescription, resources, constants)
{ {
_spdConstants = spdConstants; _spdConstants = spdConstants;
@ -129,8 +129,8 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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.UavSpdAtomicCount, Resources.SpdAtomicCounter);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel); 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) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass"); LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass");
@ -154,17 +154,15 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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;
ref var depth = ref dispatchParams.Depth;
ref var motionVectors = ref dispatchParams.MotionVectors;
ref var exposure = ref dispatchParams.Exposure;
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);
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.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
@ -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) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass"); LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass");
@ -184,23 +182,19 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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);
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);
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);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReconstructedPrevNearestDepth, Fsr2ShaderIDs.UavReconstructedPrevNearestDepth); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReconstructedPrevNearestDepth, Fsr2ShaderIDs.UavReconstructedPrevNearestDepth);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
@ -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) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_lock_pass"); 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"; private const string SharpeningKeyword = "FFX_FSR2_OPTION_APPLY_SHARPENING";
@ -241,7 +235,7 @@ namespace FidelityFX
private readonly LocalKeyword _sharpeningKeyword; private readonly LocalKeyword _sharpeningKeyword;
#endif #endif
public Fsr2AccumulatePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
public Fsr2AccumulatePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
: base(contextDescription, resources, constants) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass"); LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass");
@ -265,12 +259,17 @@ namespace FidelityFX
#endif #endif
if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
else if (dispatchParams.MotionVectors.HasValue)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value);
}
else
{
ref var motionVectors = ref dispatchParams.MotionVectors;
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement);
}
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.SrvDilatedReactiveMasks, Fsr2ShaderIDs.UavDilatedReactiveMasks); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedReactiveMasks, Fsr2ShaderIDs.UavDilatedReactiveMasks);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]);
@ -286,8 +285,8 @@ namespace FidelityFX
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLumaHistory, Resources.LumaHistory[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<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
@ -295,11 +294,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2RcasPipeline : Fsr2Pipeline
internal class Fsr2RcasPass : Fsr2Pass
{ {
private readonly ComputeBuffer _rcasConstants; 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) : base(contextDescription, resources, constants)
{ {
_rcasConstants = rcasConstants; _rcasConstants = rcasConstants;
@ -309,13 +308,12 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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]); 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<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>());
@ -324,11 +322,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2GenerateReactivePipeline : Fsr2Pipeline
internal class Fsr2GenerateReactivePass : Fsr2Pass
{ {
private readonly ComputeBuffer _generateReactiveConstants; 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) : base(contextDescription, resources, null)
{ {
_generateReactiveConstants = generateReactiveConstants; _generateReactiveConstants = generateReactiveConstants;
@ -342,14 +340,13 @@ namespace FidelityFX
public void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.GenerateReactiveDescription dispatchParams, int dispatchX, int dispatchY) 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<Fsr2.GenerateReactiveConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbGenReactive, _generateReactiveConstants, 0, Marshal.SizeOf<Fsr2.GenerateReactiveConstants>());
@ -357,11 +354,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2TcrAutogeneratePipeline : Fsr2Pipeline
internal class Fsr2TcrAutogeneratePass : Fsr2Pass
{ {
private readonly ComputeBuffer _tcrAutogenerateConstants; 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) : base(contextDescription, resources, constants)
{ {
_tcrAutogenerateConstants = tcrAutogenerateConstants; _tcrAutogenerateConstants = tcrAutogenerateConstants;
@ -371,23 +368,19 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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.SrvPrevColorPreAlpha, Resources.PrevPreAlpha[frameIndex ^ 1]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvPrevColorPostAlpha, Resources.PrevPostAlpha[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.UavAutoReactive, Resources.AutoReactive);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoComposition, Resources.AutoComposition); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoComposition, Resources.AutoComposition);

0
Assets/Scripts/Core/Fsr2Pipeline.cs.meta → Assets/Scripts/Core/Fsr2Pass.cs.meta

36
Assets/Scripts/Fsr2ImageEffect.cs

@ -301,21 +301,20 @@ namespace FidelityFX
private void SetupDispatchDescription() private void SetupDispatchDescription()
{ {
// Set up the main FSR2 dispatch parameters // 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;
if (!enableAutoExposure && exposure != null) _dispatchDescription.Exposure = exposure;
if (reactiveMask != null) _dispatchDescription.Reactive = reactiveMask;
if (transparencyAndCompositionMask != null) _dispatchDescription.TransparencyAndComposition = transparencyAndCompositionMask;
_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 = 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(); var scaledRenderSize = GetScaledRenderSize();
_dispatchDescription.Output = null;
_dispatchDescription.Output = new Fsr2.ResourceView(Fsr2ShaderIDs.UavUpscaledOutput);
_dispatchDescription.PreExposure = preExposure; _dispatchDescription.PreExposure = preExposure;
_dispatchDescription.EnableSharpening = performSharpenPass; _dispatchDescription.EnableSharpening = performSharpenPass;
_dispatchDescription.Sharpness = sharpness; _dispatchDescription.Sharpness = sharpness;
@ -334,7 +333,7 @@ namespace FidelityFX
_dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition; _dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition;
if (autoGenerateTransparencyAndComposition) if (autoGenerateTransparencyAndComposition)
{ {
_dispatchDescription.ColorOpaqueOnly = _colorOpaqueOnly;
_dispatchDescription.ColorOpaqueOnly = new Fsr2.ResourceView(_colorOpaqueOnly);
_dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold; _dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold;
_dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale; _dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale;
_dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale; _dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale;
@ -351,9 +350,9 @@ namespace FidelityFX
private void SetupAutoReactiveDescription() private void SetupAutoReactiveDescription()
{ {
// Set up the parameters to auto-generate a reactive mask // 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.RenderSize = GetScaledRenderSize();
_genReactiveDescription.Scale = generateReactiveParameters.scale; _genReactiveDescription.Scale = generateReactiveParameters.scale;
_genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold; _genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold;
@ -390,9 +389,6 @@ namespace FidelityFX
_dispatchDescription.InputResourceSize = new Vector2Int(src.width, src.height); _dispatchDescription.InputResourceSize = new Vector2Int(src.width, src.height);
_dispatchCommandBuffer.Clear(); _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) if (autoGenerateReactiveMask)
{ {
@ -400,7 +396,7 @@ namespace FidelityFX
var scaledRenderSize = GetScaledRenderSize(); var scaledRenderSize = GetScaledRenderSize();
_dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); _dispatchCommandBuffer.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
_context.GenerateReactiveMask(_genReactiveDescription, _dispatchCommandBuffer); _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 // The backbuffer is not set up to allow random-write access, so we need a temporary render texture for FSR2 to output to

39
com.unity.postprocessing/PostProcessing/Runtime/Effects/SuperResolution.cs

@ -178,10 +178,6 @@ namespace UnityEngine.Rendering.PostProcessing
CreateFsrContext(context); CreateFsrContext(context);
} }
cmd.SetGlobalTexture(Fsr2ShaderIDs.SrvInputColor, context.source);
cmd.SetGlobalTexture(Fsr2ShaderIDs.SrvInputDepth, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth);
cmd.SetGlobalTexture(Fsr2ShaderIDs.SrvInputMotionVectors, BuiltinRenderTextureType.MotionVectors);
SetupDispatchDescription(context); SetupDispatchDescription(context);
if (autoGenerateReactiveMask) if (autoGenerateReactiveMask)
@ -191,7 +187,7 @@ namespace UnityEngine.Rendering.PostProcessing
var scaledRenderSize = _genReactiveDescription.RenderSize; var scaledRenderSize = _genReactiveDescription.RenderSize;
cmd.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); cmd.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
_fsrContext.GenerateReactiveMask(_genReactiveDescription, cmd); _fsrContext.GenerateReactiveMask(_genReactiveDescription, cmd);
_dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive;
_dispatchDescription.Reactive = new Fsr2.ResourceView(Fsr2ShaderIDs.UavAutoReactive);
} }
_fsrContext.Dispatch(_dispatchDescription, cmd); _fsrContext.Dispatch(_dispatchDescription, cmd);
@ -267,22 +263,21 @@ namespace UnityEngine.Rendering.PostProcessing
var camera = context.camera; var camera = context.camera;
// Set up the main FSR2 dispatch parameters // 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); var scaledRenderSize = GetScaledRenderSize(context.camera);
_dispatchDescription.Output = context.destination;
_dispatchDescription.Output = new Fsr2.ResourceView(context.destination);
_dispatchDescription.PreExposure = preExposure; _dispatchDescription.PreExposure = preExposure;
_dispatchDescription.EnableSharpening = performSharpenPass; _dispatchDescription.EnableSharpening = performSharpenPass;
_dispatchDescription.Sharpness = sharpness; _dispatchDescription.Sharpness = sharpness;
@ -301,7 +296,7 @@ namespace UnityEngine.Rendering.PostProcessing
_dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition; _dispatchDescription.EnableAutoReactive = autoGenerateTransparencyAndComposition;
if (autoGenerateTransparencyAndComposition) if (autoGenerateTransparencyAndComposition)
{ {
_dispatchDescription.ColorOpaqueOnly = colorOpaqueOnly;
_dispatchDescription.ColorOpaqueOnly = new Fsr2.ResourceView(colorOpaqueOnly);
_dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold; _dispatchDescription.AutoTcThreshold = generateTransparencyAndCompositionParameters.autoTcThreshold;
_dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale; _dispatchDescription.AutoTcScale = generateTransparencyAndCompositionParameters.autoTcScale;
_dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale; _dispatchDescription.AutoReactiveScale = generateTransparencyAndCompositionParameters.autoReactiveScale;
@ -318,9 +313,9 @@ namespace UnityEngine.Rendering.PostProcessing
private void SetupAutoReactiveDescription(PostProcessRenderContext context) private void SetupAutoReactiveDescription(PostProcessRenderContext context)
{ {
// Set up the parameters to auto-generate a reactive mask // 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.RenderSize = GetScaledRenderSize(context.camera);
_genReactiveDescription.Scale = generateReactiveParameters.scale; _genReactiveDescription.Scale = generateReactiveParameters.scale;
_genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold; _genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold;

64
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)); 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 public enum QualityMode
{ {
UltraQuality = 0, UltraQuality = 0,
@ -157,18 +164,48 @@ namespace FidelityFX
} }
/// <summary> /// <summary>
/// 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.
/// An immutable structure wrapping all of the necessary information to bind a specific buffer or attachment of a render target to a compute shader.
/// </summary>
public readonly struct ResourceView
{
/// <summary>
/// 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.
/// </summary>
public static readonly ResourceView Unassigned = new ResourceView(default);
/// <summary>
/// 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.
/// </summary>
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;
}
/// <summary>
/// A structure encapsulating the parameters for dispatching the various passes of FidelityFX Super Resolution 2.
/// </summary> /// </summary>
public class DispatchDescription 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 JitterOffset;
public Vector2 MotionVectorScale; public Vector2 MotionVectorScale;
public Vector2Int RenderSize; public Vector2Int RenderSize;
@ -185,7 +222,7 @@ namespace FidelityFX
// EXPERIMENTAL reactive mask generation parameters // EXPERIMENTAL reactive mask generation parameters
public bool EnableAutoReactive; public bool EnableAutoReactive;
public RenderTargetIdentifier? ColorOpaqueOnly;
public ResourceView ColorOpaqueOnly;
public float AutoTcThreshold = 0.05f; public float AutoTcThreshold = 0.05f;
public float AutoTcScale = 1.0f; public float AutoTcScale = 1.0f;
public float AutoReactiveScale = 5.0f; public float AutoReactiveScale = 5.0f;
@ -193,13 +230,14 @@ namespace FidelityFX
} }
/// <summary> /// <summary>
/// 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. /// The default values for Scale, CutoffThreshold, BinaryValue and Flags were taken from the FSR2 demo project.
/// </summary> /// </summary>
public class GenerateReactiveDescription 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 Vector2Int RenderSize;
public float Scale = 0.5f; public float Scale = 0.5f;
public float CutoffThreshold = 0.2f; public float CutoffThreshold = 0.2f;

135
com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Context.cs

@ -39,14 +39,14 @@ namespace FidelityFX
private Fsr2.ContextDescription _contextDescription; private Fsr2.ContextDescription _contextDescription;
private CommandBuffer _commandBuffer; 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(); private readonly Fsr2Resources _resources = new Fsr2Resources();
@ -92,31 +92,31 @@ namespace FidelityFX
Constants.displaySize = _contextDescription.DisplaySize; Constants.displaySize = _contextDescription.DisplaySize;
_resources.Create(_contextDescription); _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() 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(); _resources.Destroy();
@ -158,9 +158,9 @@ namespace FidelityFX
// If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends // If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends
if ((_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) 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) if (dispatchParams.EnableAutoReactive)
{ {
@ -169,7 +169,10 @@ namespace FidelityFX
_resources.CreateTcrAutogenResources(_contextDescription); _resources.CreateTcrAutogenResources(_contextDescription);
if (resetAccumulation) 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) else if (_resources.AutoReactive != null)
{ {
@ -177,8 +180,8 @@ namespace FidelityFX
_resources.DestroyTcrAutogenResources(); _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); Fsr2Resources.CreateAliasableResources(commandBuffer, _contextDescription, dispatchParams);
SetupConstants(dispatchParams, resetAccumulation); SetupConstants(dispatchParams, resetAccumulation);
@ -222,24 +225,24 @@ namespace FidelityFX
if (dispatchParams.EnableAutoReactive) if (dispatchParams.EnableAutoReactive)
{ {
GenerateTransparencyCompositionReactive(dispatchParams, commandBuffer, frameIndex); 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 // Compute luminance pyramid
_computeLuminancePyramidPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y);
_computeLuminancePyramidPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y);
// Reconstruct previous depth // Reconstruct previous depth
_reconstructPreviousDepthPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
_reconstructPreviousDepthPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
// Depth clip // Depth clip
_depthClipPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
_depthClipPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
// Create locks // Create locks
_lockPipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
_lockPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
// Accumulate // Accumulate
_accumulatePipeline.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY);
_accumulatePass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY);
if (dispatchParams.EnableSharpening) if (dispatchParams.EnableSharpening)
{ {
@ -251,7 +254,7 @@ namespace FidelityFX
const int threadGroupWorkRegionDimRcas = 16; const int threadGroupWorkRegionDimRcas = 16;
int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
int threadGroupsY = (Screen.height + 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; _resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames;
@ -278,7 +281,7 @@ namespace FidelityFX
GenReactiveConsts.flags = (uint)dispatchParams.Flags; GenReactiveConsts.flags = (uint)dispatchParams.Flags;
commandBuffer.SetBufferData(_generateReactiveConstantsBuffer, _generateReactiveConstantsArray); 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) private void GenerateTransparencyCompositionReactive(Fsr2.DispatchDescription dispatchParams, CommandBuffer commandBuffer, int frameIndex)
@ -293,7 +296,7 @@ namespace FidelityFX
TcrAutoGenConsts.autoReactiveMax = dispatchParams.AutoReactiveMax; TcrAutoGenConsts.autoReactiveMax = dispatchParams.AutoReactiveMax;
commandBuffer.SetBufferData(_tcrAutogenerateConstantsBuffer, _tcrAutogenerateConstantsArray); 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) private void SetupConstants(Fsr2.DispatchDescription dispatchParams, bool resetAccumulation)
@ -353,7 +356,7 @@ namespace FidelityFX
constants.frameIndex++; constants.frameIndex++;
// Shading change usage of the SPD mip levels // Shading change usage of the SPD mip levels
constants.lumaMipLevelToUse = Fsr2Pipeline.ShadingChangeMipLevel;
constants.lumaMipLevelToUse = Fsr2Pass.ShadingChangeMipLevel;
float mipDiv = 2 << constants.lumaMipLevelToUse; float mipDiv = 2 << constants.lumaMipLevelToUse;
constants.lumaMipDimensions.x = (int)(constants.maxRenderSize.x / mipDiv); constants.lumaMipDimensions.x = (int)(constants.maxRenderSize.x / mipDiv);
@ -395,7 +398,7 @@ namespace FidelityFX
private void SetupRcasConstants(Fsr2.DispatchDescription dispatchParams) 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]; RcasConsts = RcasConfigs[sharpnessIndex];
} }
@ -433,31 +436,27 @@ namespace FidelityFX
private void DebugCheckDispatch(Fsr2.DispatchDescription dispatchParams) 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");
}
Debug.LogError("Color resource is null");
}
if (!dispatchParams.Depth.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputDepth) == null)
{
Debug.LogError("Depth resource is null");
}
if (!dispatchParams.Depth.IsValid)
{
Debug.LogError("Depth resource is null");
}
if (!dispatchParams.MotionVectors.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.SrvInputMotionVectors) == null)
{
Debug.LogError("MotionVectors resource is null");
}
if (!dispatchParams.MotionVectors.IsValid)
{
Debug.LogError("MotionVectors resource is null");
}
if (!dispatchParams.Output.HasValue && Shader.GetGlobalTexture(Fsr2ShaderIDs.UavUpscaledOutput) == null)
{
Debug.LogError("Output resource is null");
}
if (!dispatchParams.Output.IsValid)
{
Debug.LogError("Output resource is null");
} }
if (dispatchParams.Exposure.HasValue && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0)
if (dispatchParams.Exposure.IsValid && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0)
{ {
Debug.LogWarning("Exposure resource provided, however auto exposure flag is present"); 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. /// 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. /// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values.
/// </summary> /// </summary>
private static readonly List<Fsr2.RcasConstants> RcasConfigs = new List<Fsr2.RcasConstants>()
private static readonly Fsr2.RcasConstants[] RcasConfigs = new []
{ {
new Fsr2.RcasConstants(1048576000u, 872428544u), new Fsr2.RcasConstants(1048576000u, 872428544u),
new Fsr2.RcasConstants(1049178080u, 877212745u), new Fsr2.RcasConstants(1049178080u, 877212745u),
@ -595,13 +594,13 @@ namespace FidelityFX
bufferRef = null; bufferRef = null;
} }
private static void DestroyPipeline(ref Fsr2Pipeline pipeline)
private static void DestroyPass(ref Fsr2Pass pass)
{ {
if (pipeline == null)
if (pass == null)
return; return;
pipeline.Dispose();
pipeline = null;
pass.Dispose();
pass = null;
} }
} }
} }

153
com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pipeline.cs → 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. /// 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. /// These classes are responsible for loading compute shaders, managing temporary resources, binding resources to shader kernels and dispatching said shaders.
/// </summary> /// </summary>
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 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 virtual bool AllowFP16 => true;
protected Fsr2Pipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
protected Fsr2Pass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
{ {
ContextDescription = contextDescription; ContextDescription = contextDescription;
Resources = resources; Resources = resources;
@ -115,11 +115,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2ComputeLuminancePyramidPipeline : Fsr2Pipeline
internal class Fsr2ComputeLuminancePyramidPass : Fsr2Pass
{ {
private readonly ComputeBuffer _spdConstants; 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) : base(contextDescription, resources, constants)
{ {
_spdConstants = spdConstants; _spdConstants = spdConstants;
@ -129,8 +129,8 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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.UavSpdAtomicCount, Resources.SpdAtomicCounter);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel); 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) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass"); LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass");
@ -154,17 +154,15 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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;
ref var depth = ref dispatchParams.Depth;
ref var motionVectors = ref dispatchParams.MotionVectors;
ref var exposure = ref dispatchParams.Exposure;
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);
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.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
@ -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) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass"); LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass");
@ -184,23 +182,19 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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);
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);
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);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReconstructedPrevNearestDepth, Fsr2ShaderIDs.UavReconstructedPrevNearestDepth); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvReconstructedPrevNearestDepth, Fsr2ShaderIDs.UavReconstructedPrevNearestDepth);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
@ -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) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_lock_pass"); 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"; private const string SharpeningKeyword = "FFX_FSR2_OPTION_APPLY_SHARPENING";
@ -241,7 +235,7 @@ namespace FidelityFX
private readonly LocalKeyword _sharpeningKeyword; private readonly LocalKeyword _sharpeningKeyword;
#endif #endif
public Fsr2AccumulatePipeline(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
public Fsr2AccumulatePass(Fsr2.ContextDescription contextDescription, Fsr2Resources resources, ComputeBuffer constants)
: base(contextDescription, resources, constants) : base(contextDescription, resources, constants)
{ {
LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass"); LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass");
@ -265,12 +259,17 @@ namespace FidelityFX
#endif #endif
if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
else if (dispatchParams.MotionVectors.HasValue)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors.Value);
}
else
{
ref var motionVectors = ref dispatchParams.MotionVectors;
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement);
}
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.SrvDilatedReactiveMasks, Fsr2ShaderIDs.UavDilatedReactiveMasks); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvDilatedReactiveMasks, Fsr2ShaderIDs.UavDilatedReactiveMasks);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]);
@ -286,8 +285,8 @@ namespace FidelityFX
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavLumaHistory, Resources.LumaHistory[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<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
@ -295,11 +294,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2RcasPipeline : Fsr2Pipeline
internal class Fsr2RcasPass : Fsr2Pass
{ {
private readonly ComputeBuffer _rcasConstants; 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) : base(contextDescription, resources, constants)
{ {
_rcasConstants = rcasConstants; _rcasConstants = rcasConstants;
@ -309,13 +308,12 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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]); 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<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>());
@ -324,11 +322,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2GenerateReactivePipeline : Fsr2Pipeline
internal class Fsr2GenerateReactivePass : Fsr2Pass
{ {
private readonly ComputeBuffer _generateReactiveConstants; 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) : base(contextDescription, resources, null)
{ {
_generateReactiveConstants = generateReactiveConstants; _generateReactiveConstants = generateReactiveConstants;
@ -342,14 +340,13 @@ namespace FidelityFX
public void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.GenerateReactiveDescription dispatchParams, int dispatchX, int dispatchY) 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<Fsr2.GenerateReactiveConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbGenReactive, _generateReactiveConstants, 0, Marshal.SizeOf<Fsr2.GenerateReactiveConstants>());
@ -357,11 +354,11 @@ namespace FidelityFX
} }
} }
internal class Fsr2TcrAutogeneratePipeline : Fsr2Pipeline
internal class Fsr2TcrAutogeneratePass : Fsr2Pass
{ {
private readonly ComputeBuffer _tcrAutogenerateConstants; 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) : base(contextDescription, resources, constants)
{ {
_tcrAutogenerateConstants = tcrAutogenerateConstants; _tcrAutogenerateConstants = tcrAutogenerateConstants;
@ -371,23 +368,19 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) 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.SrvPrevColorPreAlpha, Resources.PrevPreAlpha[frameIndex ^ 1]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvPrevColorPostAlpha, Resources.PrevPostAlpha[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.UavAutoReactive, Resources.AutoReactive);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoComposition, Resources.AutoComposition); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoComposition, Resources.AutoComposition);

0
com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pipeline.cs.meta → com.unity.postprocessing/PostProcessing/Runtime/FSR2/Fsr2Pass.cs.meta

Loading…
Cancel
Save