Browse Source

Refactored loading of FSR3 compute shaders, using an aggregate object containing pre-loaded compute shaders instead of the old callbacks.

This gives more control to the application about how shaders are loaded/unloaded, and it fits in much more nicely with PPV2's resources.
Shaders are currently just serialized as part of the scene component, which isn't the optimal solution yet.
fsr3
Nico de Poel 2 years ago
parent
commit
84e5e72ab7
  1. 10
      Assets/Scenes/SampleScene.unity
  2. 4
      Assets/Scripts/Core/Fsr3Upscaler.cs
  3. 13
      Assets/Scripts/Core/Fsr3UpscalerCallbacks.cs
  4. 8
      Assets/Scripts/Core/Fsr3UpscalerContext.cs
  5. 64
      Assets/Scripts/Core/Fsr3UpscalerPass.cs
  6. 60
      Assets/Scripts/Core/Fsr3UpscalerShaders.cs
  7. 11
      Assets/Scripts/Core/Fsr3UpscalerShaders.cs.meta
  8. 31
      Assets/Scripts/Fsr3UpscalerImageEffect.cs

10
Assets/Scenes/SampleScene.unity

@ -337,7 +337,15 @@ MonoBehaviour:
autoTcScale: 1
autoReactiveScale: 5
autoReactiveMax: 0.9
outputMotionVectors: {fileID: 0}
shaders:
computeLuminancePyramidPass: {fileID: 7200000, guid: d253be05abcdc80428503d3e4cce3a36, type: 3}
reconstructPreviousDepthPass: {fileID: 7200000, guid: 4f59e5b9179d74844ae06a30ae1e0629, type: 3}
depthClipPass: {fileID: 7200000, guid: 20e44016ed34b0d4b8de499d1b566c69, type: 3}
lockPass: {fileID: 7200000, guid: a135306e6d1857e43a86ef20db2a47fe, type: 3}
accumulatePass: {fileID: 7200000, guid: c9b45f0ae7673694ba57a4aadfe212e9, type: 3}
sharpenPass: {fileID: 7200000, guid: 7aaf5cfff022de2499e9b0412f947f6c, type: 3}
autoGenReactivePass: {fileID: 7200000, guid: 5716b91fdaa4e9e439df6b96a796fe6e, type: 3}
tcrAutoGenPass: {fileID: 7200000, guid: 75cdc6ef23f08ed498d4da511923fcea, type: 3}
--- !u!114 &963194230
MonoBehaviour:
m_ObjectHideFlags: 0

4
Assets/Scripts/Core/Fsr3Upscaler.cs

@ -33,7 +33,7 @@ namespace FidelityFX
/// <summary>
/// Creates a new FSR3 Upscaler context with standard parameters that are appropriate for the current platform.
/// </summary>
public static Fsr3UpscalerContext CreateContext(Vector2Int displaySize, Vector2Int maxRenderSize, IFsr3UpscalerCallbacks callbacks, InitializationFlags flags = 0)
public static Fsr3UpscalerContext CreateContext(Vector2Int displaySize, Vector2Int maxRenderSize, Fsr3UpscalerShaders shaders, IFsr3UpscalerCallbacks callbacks, InitializationFlags flags = 0)
{
if (SystemInfo.usesReversedZBuffer)
flags |= InitializationFlags.EnableDepthInverted;
@ -51,6 +51,7 @@ namespace FidelityFX
Flags = flags,
DisplaySize = displaySize,
MaxRenderSize = maxRenderSize,
Shaders = shaders,
Callbacks = callbacks,
};
@ -166,6 +167,7 @@ namespace FidelityFX
public InitializationFlags Flags;
public Vector2Int MaxRenderSize;
public Vector2Int DisplaySize;
public Fsr3UpscalerShaders Shaders;
public IFsr3UpscalerCallbacks Callbacks;
}

13
Assets/Scripts/Core/Fsr3UpscalerCallbacks.cs

@ -28,9 +28,6 @@ namespace FidelityFX
/// </summary>
public interface IFsr3UpscalerCallbacks
{
ComputeShader LoadComputeShader(string name);
void UnloadComputeShader(ComputeShader shader);
/// <summary>
/// Apply a mipmap bias to in-game textures to prevent them from becoming blurry as the internal rendering resolution lowers.
/// This will need to be customized on a per-game basis, as there is no clear universal way to determine what are "in-game" textures.
@ -52,16 +49,6 @@ namespace FidelityFX
{
protected float CurrentBiasOffset = 0;
public virtual ComputeShader LoadComputeShader(string name)
{
return Resources.Load<ComputeShader>(name);
}
public virtual void UnloadComputeShader(ComputeShader shader)
{
Resources.UnloadAsset(shader);
}
public virtual void ApplyMipmapBias(float biasOffset)
{
if (float.IsNaN(biasOffset) || float.IsInfinity(biasOffset))

8
Assets/Scripts/Core/Fsr3UpscalerContext.cs

@ -42,7 +42,7 @@ namespace FidelityFX
private Fsr3UpscalerPass _reconstructPreviousDepthPass;
private Fsr3UpscalerPass _lockPass;
private Fsr3UpscalerPass _accumulatePass;
private Fsr3UpscalerPass _rcasPass;
private Fsr3UpscalerPass _sharpenPass;
private Fsr3UpscalerPass _computeLuminancePyramidPass;
private Fsr3UpscalerPass _generateReactivePass;
private Fsr3UpscalerPass _tcrAutogeneratePass;
@ -101,7 +101,7 @@ namespace FidelityFX
_depthClipPass = new Fsr3UpscalerDepthClipPass(_contextDescription, _resources, _upscalerConstantsBuffer);
_lockPass = new Fsr3UpscalerLockPass(_contextDescription, _resources, _upscalerConstantsBuffer);
_accumulatePass = new Fsr3UpscalerAccumulatePass(_contextDescription, _resources, _upscalerConstantsBuffer);
_rcasPass = new Fsr3UpscalerRcasPass(_contextDescription, _resources, _upscalerConstantsBuffer, _rcasConstantsBuffer);
_sharpenPass = new Fsr3UpscalerSharpenPass(_contextDescription, _resources, _upscalerConstantsBuffer, _rcasConstantsBuffer);
_generateReactivePass = new Fsr3UpscalerGenerateReactivePass(_contextDescription, _resources, _generateReactiveConstantsBuffer);
_tcrAutogeneratePass = new Fsr3UpscalerTcrAutogeneratePass(_contextDescription, _resources, _upscalerConstantsBuffer, _tcrAutogenerateConstantsBuffer);
}
@ -111,7 +111,7 @@ namespace FidelityFX
DestroyPass(ref _tcrAutogeneratePass);
DestroyPass(ref _generateReactivePass);
DestroyPass(ref _computeLuminancePyramidPass);
DestroyPass(ref _rcasPass);
DestroyPass(ref _sharpenPass);
DestroyPass(ref _accumulatePass);
DestroyPass(ref _lockPass);
DestroyPass(ref _reconstructPreviousDepthPass);
@ -258,7 +258,7 @@ namespace FidelityFX
const int threadGroupWorkRegionDimRcas = 16;
int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
_rcasPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY);
_sharpenPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY);
}
_resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames;

64
Assets/Scripts/Core/Fsr3UpscalerPass.cs

@ -50,26 +50,24 @@ namespace FidelityFX
public virtual void Dispose()
{
UnloadComputeShader();
}
public abstract void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY);
protected void LoadComputeShader(string name)
protected void InitComputeShader(string passName, ComputeShader shader)
{
LoadComputeShader(name, ContextDescription.Flags, ref ComputeShader, out KernelIndex);
InitComputeShader(passName, shader, ContextDescription.Flags);
}
private void LoadComputeShader(string name, Fsr3Upscaler.InitializationFlags flags, ref ComputeShader shaderRef, out int kernelIndex)
private void InitComputeShader(string passName, ComputeShader shader, Fsr3Upscaler.InitializationFlags flags)
{
if (shaderRef == null)
if (shader == null)
{
shaderRef = ContextDescription.Callbacks.LoadComputeShader(name);
if (shaderRef == null)
throw new MissingReferenceException($"Shader '{name}' could not be loaded! Please ensure it is included in the project correctly.");
throw new MissingReferenceException($"Shader for FSR3 Upscaler '{passName}' could not be loaded! Please ensure it is included in the project correctly.");
}
kernelIndex = shaderRef.FindKernel("CS");
ComputeShader = shader;
KernelIndex = ComputeShader.FindKernel("CS");
bool useLut = false;
#if UNITY_2022_1_OR_NEWER // This will also work in 2020.3.43+ and 2021.3.14+
@ -80,34 +78,20 @@ namespace FidelityFX
#endif
// This matches the permutation rules from the CreatePipeline* functions
if ((flags & Fsr3Upscaler.InitializationFlags.EnableHighDynamicRange) != 0) shaderRef.EnableKeyword("FFX_FSR3UPSCALER_OPTION_HDR_COLOR_INPUT");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) shaderRef.EnableKeyword("FFX_FSR3UPSCALER_OPTION_LOW_RESOLUTION_MOTION_VECTORS");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0) shaderRef.EnableKeyword("FFX_FSR3UPSCALER_OPTION_JITTERED_MOTION_VECTORS");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableDepthInverted) != 0) shaderRef.EnableKeyword("FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH");
if (useLut) shaderRef.EnableKeyword("FFX_FSR3UPSCALER_OPTION_REPROJECT_USE_LANCZOS_TYPE");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableFP16Usage) != 0) shaderRef.EnableKeyword("FFX_HALF");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableHighDynamicRange) != 0) ComputeShader.EnableKeyword("FFX_FSR3UPSCALER_OPTION_HDR_COLOR_INPUT");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) ComputeShader.EnableKeyword("FFX_FSR3UPSCALER_OPTION_LOW_RESOLUTION_MOTION_VECTORS");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0) ComputeShader.EnableKeyword("FFX_FSR3UPSCALER_OPTION_JITTERED_MOTION_VECTORS");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableDepthInverted) != 0) ComputeShader.EnableKeyword("FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH");
if (useLut) ComputeShader.EnableKeyword("FFX_FSR3UPSCALER_OPTION_REPROJECT_USE_LANCZOS_TYPE");
if ((flags & Fsr3Upscaler.InitializationFlags.EnableFP16Usage) != 0) ComputeShader.EnableKeyword("FFX_HALF");
// Inform the shader which render pipeline we're currently using
var pipeline = GraphicsSettings.currentRenderPipeline;
if (pipeline != null && pipeline.GetType().Name.Contains("HDRenderPipeline"))
{
shaderRef.EnableKeyword("UNITY_FSR3UPSCALER_HDRP");
ComputeShader.EnableKeyword("UNITY_FSR3UPSCALER_HDRP");
}
}
private void UnloadComputeShader()
{
UnloadComputeShader(ref ComputeShader);
}
private void UnloadComputeShader(ref ComputeShader shaderRef)
{
if (shaderRef == null)
return;
ContextDescription.Callbacks.UnloadComputeShader(shaderRef);
shaderRef = null;
}
}
internal class Fsr3UpscalerComputeLuminancePyramidPass : Fsr3UpscalerPass
@ -119,7 +103,7 @@ namespace FidelityFX
{
_spdConstants = spdConstants;
LoadComputeShader("FSR3/ffx_fsr3upscaler_compute_luminance_pyramid_pass");
InitComputeShader("compute_luminance_pyramid_pass", contextDescription.Shaders.computeLuminancePyramidPass);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
@ -144,7 +128,7 @@ namespace FidelityFX
public Fsr3UpscalerReconstructPreviousDepthPass(Fsr3Upscaler.ContextDescription contextDescription, Fsr3UpscalerResources resources, ComputeBuffer constants)
: base(contextDescription, resources, constants)
{
LoadComputeShader("FSR3/ffx_fsr3upscaler_reconstruct_previous_depth_pass");
InitComputeShader("reconstruct_previous_depth_pass", contextDescription.Shaders.reconstructPreviousDepthPass);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
@ -172,7 +156,7 @@ namespace FidelityFX
public Fsr3UpscalerDepthClipPass(Fsr3Upscaler.ContextDescription contextDescription, Fsr3UpscalerResources resources, ComputeBuffer constants)
: base(contextDescription, resources, constants)
{
LoadComputeShader("FSR3/ffx_fsr3upscaler_depth_clip_pass");
InitComputeShader("depth_clip_pass", contextDescription.Shaders.depthClipPass);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
@ -207,7 +191,7 @@ namespace FidelityFX
public Fsr3UpscalerLockPass(Fsr3Upscaler.ContextDescription contextDescription, Fsr3UpscalerResources resources, ComputeBuffer constants)
: base(contextDescription, resources, constants)
{
LoadComputeShader("FSR3/ffx_fsr3upscaler_lock_pass");
InitComputeShader("lock_pass", contextDescription.Shaders.lockPass);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
@ -230,7 +214,7 @@ namespace FidelityFX
public Fsr3UpscalerAccumulatePass(Fsr3Upscaler.ContextDescription contextDescription, Fsr3UpscalerResources resources, ComputeBuffer constants)
: base(contextDescription, resources, constants)
{
LoadComputeShader("FSR3/ffx_fsr3upscaler_accumulate_pass");
InitComputeShader("accumulate_pass", contextDescription.Shaders.accumulatePass);
#if UNITY_2021_2_OR_NEWER
_sharpeningKeyword = new LocalKeyword(ComputeShader, SharpeningKeyword);
#endif
@ -286,16 +270,16 @@ namespace FidelityFX
}
}
internal class Fsr3UpscalerRcasPass : Fsr3UpscalerPass
internal class Fsr3UpscalerSharpenPass : Fsr3UpscalerPass
{
private readonly ComputeBuffer _rcasConstants;
public Fsr3UpscalerRcasPass(Fsr3Upscaler.ContextDescription contextDescription, Fsr3UpscalerResources resources, ComputeBuffer constants, ComputeBuffer rcasConstants)
public Fsr3UpscalerSharpenPass(Fsr3Upscaler.ContextDescription contextDescription, Fsr3UpscalerResources resources, ComputeBuffer constants, ComputeBuffer rcasConstants)
: base(contextDescription, resources, constants)
{
_rcasConstants = rcasConstants;
LoadComputeShader("FSR3/ffx_fsr3upscaler_rcas_pass");
InitComputeShader("rcas_pass", contextDescription.Shaders.sharpenPass);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
@ -323,7 +307,7 @@ namespace FidelityFX
{
_generateReactiveConstants = generateReactiveConstants;
LoadComputeShader("FSR3/ffx_fsr3upscaler_autogen_reactive_pass");
InitComputeShader("autogen_reactive_pass", contextDescription.Shaders.autoGenReactivePass);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
@ -355,7 +339,7 @@ namespace FidelityFX
{
_tcrAutogenerateConstants = tcrAutogenerateConstants;
LoadComputeShader("FSR3/ffx_fsr3upscaler_tcr_autogen_pass");
InitComputeShader("tcr_autogen_pass", contextDescription.Shaders.tcrAutoGenPass);
}
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr3Upscaler.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)

60
Assets/Scripts/Core/Fsr3UpscalerShaders.cs

@ -0,0 +1,60 @@
using System;
using UnityEngine;
namespace FidelityFX
{
/// <summary>
/// All the compute shaders used by the FidelityFX Super Resolution 3 (FSR3) Upscaler.
/// </summary>
[Serializable]
public class Fsr3UpscalerShaders
{
/// <summary>
/// The compute shader used by the luminance pyramid computation pass.
/// </summary>
public ComputeShader computeLuminancePyramidPass;
/// <summary>
/// The compute shader used by the previous depth reconstruction pass.
/// </summary>
public ComputeShader reconstructPreviousDepthPass;
/// <summary>
/// The compute shader used by the depth clip pass.
/// </summary>
public ComputeShader depthClipPass;
/// <summary>
/// The compute shader used by the lock pass.
/// </summary>
public ComputeShader lockPass;
/// <summary>
/// The compute shader used by the accumulation pass.
/// </summary>
public ComputeShader accumulatePass;
/// <summary>
/// The compute shader used by the RCAS sharpening pass.
/// </summary>
public ComputeShader sharpenPass;
/// <summary>
/// The compute shader used to auto-generate a reactive mask.
/// </summary>
public ComputeShader autoGenReactivePass;
/// <summary>
/// The compute shader used to auto-generate a transparency & composition mask.
/// </summary>
public ComputeShader tcrAutoGenPass;
/// <summary>
/// Returns a copy of this class and its contents.
/// </summary>
public Fsr3UpscalerShaders Clone()
{
return (Fsr3UpscalerShaders)MemberwiseClone();
}
}
}

11
Assets/Scripts/Core/Fsr3UpscalerShaders.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db26e15a33db6ab42a38daab0ba2712f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

31
Assets/Scripts/Fsr3UpscalerImageEffect.cs

@ -98,8 +98,8 @@ namespace FidelityFX
[Range(0, 1)] public float autoReactiveMax = 0.9f;
}
[Header("Slave cameras")]
public Fsr3UpscalerCameraHelper[] cameraStack;
[SerializeField]
private Fsr3UpscalerShaders shaders;
private Fsr3UpscalerContext _context;
private Vector2Int _maxRenderSize;
@ -159,26 +159,10 @@ namespace FidelityFX
CreateFsrContext();
CreateCommandBuffers();
if (cameraStack != null)
{
foreach (var cameraHelper in cameraStack)
{
cameraHelper.enabled = true;
}
}
}
private void OnDisable()
{
if (cameraStack != null)
{
foreach (var cameraHelper in cameraStack)
{
cameraHelper.enabled = false;
}
}
DestroyCommandBuffers();
DestroyFsrContext();
@ -202,7 +186,7 @@ namespace FidelityFX
if (enableAutoExposure) flags |= Fsr3Upscaler.InitializationFlags.EnableAutoExposure;
if (UsingDynamicResolution()) flags |= Fsr3Upscaler.InitializationFlags.EnableDynamicResolution;
_context = Fsr3Upscaler.CreateContext(_displaySize, _maxRenderSize, Callbacks, flags);
_context = Fsr3Upscaler.CreateContext(_displaySize, _maxRenderSize, shaders, Callbacks, flags);
_prevDisplaySize = _displaySize;
_prevQualityMode = qualityMode;
@ -271,15 +255,6 @@ namespace FidelityFX
OnDisable();
OnEnable();
}
if (cameraStack != null)
{
int numCams = cameraStack.Length;
for (int i = 0; i < numCams; ++i)
{
cameraStack[i].qualityMode = qualityMode;
}
}
}
public void ResetHistory()

Loading…
Cancel
Save