Browse Source

Started work on luminance pyramid and acculumate pipelines.

Added keywords for customization options to the compute shaders using multi_compile_local.
mac-autoexp
Nico de Poel 3 years ago
parent
commit
913c5879fa
  1. 8
      Assets/Resources/FSR2/ffx_fsr2_accumulate_pass.compute
  2. 8
      Assets/Resources/FSR2/ffx_fsr2_autogen_reactive_pass.compute
  3. 8
      Assets/Resources/FSR2/ffx_fsr2_compute_luminance_pyramid_pass.compute
  4. 8
      Assets/Resources/FSR2/ffx_fsr2_depth_clip_pass.compute
  5. 8
      Assets/Resources/FSR2/ffx_fsr2_lock_pass.compute
  6. 8
      Assets/Resources/FSR2/ffx_fsr2_prepare_input_color_pass.compute
  7. 9
      Assets/Resources/FSR2/ffx_fsr2_rcas_pass.compute
  8. 8
      Assets/Resources/FSR2/ffx_fsr2_reconstruct_previous_depth_pass.compute
  9. 8
      Assets/Resources/FSR2/ffx_fsr2_tcr_autogen_pass.compute
  10. 64
      Assets/Scripts/Fsr2Context.cs
  11. 97
      Assets/Scripts/Fsr2Pipeline.cs

8
Assets/Resources/FSR2/ffx_fsr2_accumulate_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
#pragma multi_compile_local __ FFX_HALF
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL

8
Assets/Resources/FSR2/ffx_fsr2_autogen_reactive_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
#pragma multi_compile_local __ FFX_HALF
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL

8
Assets/Resources/FSR2/ffx_fsr2_compute_luminance_pyramid_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
//#pragma multi_compile_local __ FFX_HALF // causes a hard-coded error message from the shader include ¯\_(ツ)_/¯
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL
#define SPD_NO_WAVE_OPERATIONS // Wave operations require shader model 6.0; this works with #pragma use_dxc but only on D3D12

8
Assets/Resources/FSR2/ffx_fsr2_depth_clip_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
#pragma multi_compile_local __ FFX_HALF
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL

8
Assets/Resources/FSR2/ffx_fsr2_lock_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
#pragma multi_compile_local __ FFX_HALF
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL

8
Assets/Resources/FSR2/ffx_fsr2_prepare_input_color_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
#pragma multi_compile_local __ FFX_HALF
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL

9
Assets/Resources/FSR2/ffx_fsr2_rcas_pass.compute

@ -1,7 +1,12 @@
// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CS
//#pragma kernel CS_HALF CS=CS_HALF FFX_HALF
//#pragma kernel CS_HDR CS=CS_HDR FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
// Some global defines are needed
#define FFX_GPU // Compiling for GPU

8
Assets/Resources/FSR2/ffx_fsr2_reconstruct_previous_depth_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
#pragma multi_compile_local __ FFX_HALF
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL

8
Assets/Resources/FSR2/ffx_fsr2_tcr_autogen_pass.compute

@ -1,5 +1,13 @@
#pragma kernel CS
#pragma multi_compile_local __ FFX_HALF
#pragma multi_compile_local __ FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE
#pragma multi_compile_local __ FFX_FSR2_OPTION_HDR_COLOR_INPUT
#pragma multi_compile_local __ FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS
#pragma multi_compile_local __ FFX_FSR2_OPTION_INVERTED_DEPTH
#pragma multi_compile_local __ FFX_FSR2_OPTION_APPLY_SHARPENING
#define FFX_GPU // Compiling for GPU
#define FFX_HLSL // Compile for plain HLSL

64
Assets/Scripts/Fsr2Context.cs

@ -55,6 +55,7 @@ namespace FidelityFX
// Set defaults
_firstExecution = true;
_resourceFrameIndex = 0;
Constants.displaySize = _contextDescription.DisplaySize;
// Generate the data for the LUT
@ -91,11 +92,36 @@ namespace FidelityFX
private void InitPipelines()
{
_rcasPipeline = new Fsr2RcasPipeline(_contextDescription.Callbacks, _fsr2ConstantsBuffer, _rcasConstantsBuffer);
_computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer);
_accumulatePipeline = new Fsr2AccumulatePipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer);
_accumulateSharpenPipeline = new Fsr2AccumulateSharpenPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer);
_rcasPipeline = new Fsr2RcasPipeline(_contextDescription.Callbacks, _contextDescription.Flags, _fsr2ConstantsBuffer, _rcasConstantsBuffer);
}
public void Destroy()
{
DisposePipeline(ref _tcrAutogeneratePipeline);
DisposePipeline(ref _generateReactivePipeline);
DisposePipeline(ref _computeLuminancePyramidPipeline);
DisposePipeline(ref _rcasPipeline);
DisposePipeline(ref _accumulateSharpenPipeline);
DisposePipeline(ref _accumulatePipeline);
DisposePipeline(ref _lockPipeline);
DisposePipeline(ref _reconstructPreviousDepthPipeline);
DisposePipeline(ref _depthClipPipeline);
DestroyConstantBuffer(ref _rcasConstantsBuffer);
DestroyConstantBuffer(ref _spdConstantsBuffer);
DestroyConstantBuffer(ref _fsr2ConstantsBuffer);
_commandBuffer.Dispose();
_commandBuffer = null;
}
public void Dispatch(Fsr2.DispatchDescription dispatchParams)
{
// TODO: validation & debug checking
_commandBuffer.Clear();
// TODO: Should probably use a CommandBuffer here, to queue up all of the commands and dispatch them in one go
@ -136,9 +162,9 @@ namespace FidelityFX
_fsr2ConstantsBuffer.SetData(_fsr2ConstantsArray);
_spdConstantsBuffer.SetData(_spdConstantsArray);
// // Compute luminance pyramid
// _commandBuffer.DispatchCompute(_computeLuminancePyramidShader, _computeLuminancePyramidKernel, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y, 1);
//
// Compute luminance pyramid
_computeLuminancePyramidPipeline.ScheduleDispatch(_commandBuffer, dispatchParams, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y);
// // Reconstruct previous depth
// _commandBuffer.DispatchCompute(_reconstructPreviousDepthShader, _reconstructPreviousDepthKernel, dispatchSrcX, dispatchSrcY, 1);
//
@ -148,10 +174,14 @@ namespace FidelityFX
// // Lock
// _commandBuffer.DispatchCompute(_lockShader, _lockKernel, dispatchSrcX, dispatchSrcY, 1);
//
// // Accumulate
// _commandBuffer.DispatchCompute(_accumulateShader, _accumulateKernel, dispatchDstX, dispatchDstY, 1); // TODO: accumulate + sharpen
if (dispatchParams.EnableSharpening)
bool sharpenEnabled = dispatchParams.EnableSharpening;
// Accumulate
var accumulatePipeline = sharpenEnabled ? _accumulateSharpenPipeline : _accumulatePipeline;
accumulatePipeline.ScheduleDispatch(_commandBuffer, dispatchParams, dispatchDstX, dispatchDstY);
if (sharpenEnabled)
{
// Compute the constants
SetupRcasConstants(dispatchParams);
@ -322,26 +352,6 @@ namespace FidelityFX
}
}
public void Destroy()
{
DisposePipeline(ref _tcrAutogeneratePipeline);
DisposePipeline(ref _generateReactivePipeline);
DisposePipeline(ref _computeLuminancePyramidPipeline);
DisposePipeline(ref _rcasPipeline);
DisposePipeline(ref _accumulateSharpenPipeline);
DisposePipeline(ref _accumulatePipeline);
DisposePipeline(ref _lockPipeline);
DisposePipeline(ref _reconstructPreviousDepthPipeline);
DisposePipeline(ref _depthClipPipeline);
DestroyConstantBuffer(ref _rcasConstantsBuffer);
DestroyConstantBuffer(ref _spdConstantsBuffer);
DestroyConstantBuffer(ref _fsr2ConstantsBuffer);
_commandBuffer.Dispose();
_commandBuffer = null;
}
/// <summary>
/// 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.

97
Assets/Scripts/Fsr2Pipeline.cs

@ -7,14 +7,16 @@ namespace FidelityFX
{
internal abstract class Fsr2Pipeline: IDisposable
{
private readonly Fsr2Callbacks _callbacks;
protected readonly ComputeBuffer Constants;
protected ComputeShader ComputeShader;
protected int KernelIndex;
private readonly Fsr2Callbacks _callbacks;
protected Fsr2Pipeline(Fsr2Callbacks callbacks)
protected Fsr2Pipeline(Fsr2Callbacks callbacks, ComputeBuffer constants)
{
_callbacks = callbacks;
Constants = constants;
}
public virtual void Dispose()
@ -24,25 +26,32 @@ namespace FidelityFX
public abstract void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY);
protected void LoadComputeShader(string name)
protected void LoadComputeShader(string name, Fsr2.InitializationFlags flags)
{
LoadComputeShader(name, ref ComputeShader, out KernelIndex);
LoadComputeShader(name, flags, ref ComputeShader, out KernelIndex);
}
protected void LoadComputeShader(string name, ref ComputeShader shaderRef, out int kernelIndex)
private void LoadComputeShader(string name, Fsr2.InitializationFlags flags, ref ComputeShader shaderRef, out int kernelIndex)
{
if (shaderRef == null)
shaderRef = _callbacks.LoadComputeShader(name);
kernelIndex = shaderRef.FindKernel("CS");
if ((flags & Fsr2.InitializationFlags.EnableHighDynamicRange) != 0) shaderRef.EnableKeyword("FFX_FSR2_OPTION_HDR_COLOR_INPUT");
if ((flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) shaderRef.EnableKeyword("FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS");
if ((flags & Fsr2.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0) shaderRef.EnableKeyword("FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS");
if ((flags & Fsr2.InitializationFlags.EnableDepthInverted) != 0) shaderRef.EnableKeyword("FFX_FSR2_OPTION_INVERTED_DEPTH");
// TODO: enable FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE if the device capabilities allow (default subgroup size == 32 or 64)
// TODO: enable FFX_HALF if FP16 is supported (except RCAS)
}
protected void UnloadComputeShader()
private void UnloadComputeShader()
{
UnloadComputeShader(ref ComputeShader);
}
protected void UnloadComputeShader(ref ComputeShader shaderRef)
private void UnloadComputeShader(ref ComputeShader shaderRef)
{
if (shaderRef == null)
return;
@ -52,18 +61,78 @@ namespace FidelityFX
}
}
internal class Fsr2ComputeLuminancePyramidPipeline : Fsr2Pipeline
{
public Fsr2ComputeLuminancePyramidPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants)
: base(callbacks, constants)
{
LoadComputeShader("FSR2/ffx_fsr2_compute_luminance_pyramid_pass", flags);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY)
{
//throw new NotImplementedException();
}
}
internal class Fsr2AccumulatePipeline : Fsr2Pipeline
{
public Fsr2AccumulatePipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants)
: base(callbacks, constants)
{
LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass", flags);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY)
{
//throw new NotImplementedException();
}
}
internal class Fsr2AccumulateSharpenPipeline : Fsr2AccumulatePipeline
{
private readonly ComputeShader _shaderCopy;
public Fsr2AccumulateSharpenPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants)
: base(callbacks, flags, constants)
{
// Simply loading the accumulate_pass compute shader will give us the same instance as the non-sharpen pipeline
// So we have to clone the shader instance and set the extra keyword on the new copy
_shaderCopy = UnityEngine.Object.Instantiate(ComputeShader);
foreach (var keyword in ComputeShader.enabledKeywords)
{
_shaderCopy.EnableKeyword(keyword.name);
}
_shaderCopy.EnableKeyword("FFX_FSR2_OPTION_APPLY_SHARPENING");
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY)
{
// Temporarily swap around the shaders so that the dispatch will bind and execute the correct one
ComputeShader tmp = ComputeShader;
ComputeShader = _shaderCopy;
base.ScheduleDispatch(commandBuffer, dispatchParams, dispatchX, dispatchY);
ComputeShader = tmp;
}
public override void Dispose()
{
// Since we instantiated this copy, we have to destroy it instead of unloading the shader resource
UnityEngine.Object.Destroy(_shaderCopy);
base.Dispose();
}
}
internal class Fsr2RcasPipeline : Fsr2Pipeline
{
private readonly ComputeBuffer _fsr2Constants;
private readonly ComputeBuffer _rcasConstants;
public Fsr2RcasPipeline(Fsr2Callbacks callbacks, ComputeBuffer fsr2Constants, ComputeBuffer rcasConstants)
: base(callbacks)
public Fsr2RcasPipeline(Fsr2Callbacks callbacks, Fsr2.InitializationFlags flags, ComputeBuffer constants, ComputeBuffer rcasConstants)
: base(callbacks, constants)
{
_fsr2Constants = fsr2Constants;
_rcasConstants = rcasConstants;
LoadComputeShader("FSR2/ffx_fsr2_rcas_pass");
LoadComputeShader("FSR2/ffx_fsr2_rcas_pass", flags);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY)
@ -72,7 +141,7 @@ namespace FidelityFX
ComputeShader.SetTexture(KernelIndex, "r_input_exposure", dispatchParams.Exposure);
ComputeShader.SetTexture(KernelIndex, "r_rcas_input", dispatchParams.Input);
ComputeShader.SetTexture(KernelIndex, "rw_upscaled_output", dispatchParams.Output);
ComputeShader.SetConstantBuffer("cbFSR2", _fsr2Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
ComputeShader.SetConstantBuffer("cbFSR2", Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
ComputeShader.SetConstantBuffer("cbRCAS", _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>());
commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);

Loading…
Cancel
Save