Browse Source

Went back to the vanilla FSR 3.1.1 package code and removed all CAS and standalone reactive mask code, to make the Upscaler abstraction as clean as possible.

dec2024update
Nico de Poel 1 year ago
parent
commit
509950b879
  1. 2
      Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/FSR2Upscaler.cs
  2. 2
      Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/FSR3Upscaler.cs
  3. 193
      Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Upscaler.cs
  4. 2
      Packages/fidelityfx.fsr

2
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/FSR2Upscaler.cs

@ -26,8 +26,6 @@ namespace UnityEngine.Rendering.PostProcessing
public override void DestroyContext()
{
base.DestroyContext();
if (_fsrContext != null)
{
_fsrContext.Destroy();

2
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/FSR3Upscaler.cs

@ -26,8 +26,6 @@ namespace UnityEngine.Rendering.PostProcessing
public override void DestroyContext()
{
base.DestroyContext();
if (_fsrContext != null)
{
_fsrContext.Destroy();

193
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Upscaler.cs

@ -1,8 +1,4 @@
using System;
using System.Runtime.InteropServices;
using FidelityFX;
using FidelityFX.FSR2;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Rendering.PostProcessing
{
@ -10,195 +6,8 @@ namespace UnityEngine.Rendering.PostProcessing
{
public abstract void CreateContext(PostProcessRenderContext context, Upscaling config);
public virtual void DestroyContext()
{
DestroyRenderTexture(ref _reactiveMask);
DestroyConstantsBuffer(ref _reactiveMaskConstants);
DestroyConstantsBuffer(ref _sharpeningConstants);
}
public abstract void DestroyContext();
public abstract void Render(PostProcessRenderContext context, Upscaling config);
private ConstantsBuffer<GenerateReactiveConstants> _reactiveMaskConstants;
private RenderTexture _reactiveMask;
/// <summary>
/// Generalized standalone version of the FSR2 reactive mask auto-generating pass that can be used without needing an active FSR2 context.
/// This allows auto-generated reactive masks to be reused for other non-FSR upscaling techniques.
/// </summary>
protected Texture GenerateReactiveMask(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config, GraphicsFormat format = GraphicsFormat.R8_UNorm)
{
ComputeShader shader = context.resources.computeShaders.fsr2Upscaler?.autoGenReactivePass;
if (shader == null)
return Texture2D.blackTexture;
_reactiveMaskConstants ??= ConstantsBuffer<GenerateReactiveConstants>.Create();
if (_reactiveMask == null)
{
// Use a persistent RT so it can easily be passed to native render plugins
CreateRenderTexture(ref _reactiveMask, "Reactive Mask", config.MaxRenderSize, format, true);
}
Vector2Int scaledRenderSize = config.GetScaledRenderSize(context.camera);
const int threadGroupWorkRegionDim = 8;
int dispatchX = (scaledRenderSize.x + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
int dispatchY = (scaledRenderSize.y + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
cmd.BeginSample("Generate Reactive Mask");
_reactiveMaskConstants.Value.scale = config.generateReactiveParameters.scale;
_reactiveMaskConstants.Value.threshold = config.generateReactiveParameters.cutoffThreshold;
_reactiveMaskConstants.Value.binaryValue = config.generateReactiveParameters.binaryValue;
_reactiveMaskConstants.Value.flags = (uint)config.generateReactiveParameters.flags;
_reactiveMaskConstants.UpdateBufferData(cmd);
int kernelIndex = shader.FindKernel("CS");
cmd.SetComputeTextureParam(shader, kernelIndex, Fsr2ShaderIDs.SrvOpaqueOnly, config.ColorOpaqueOnly);
cmd.SetComputeTextureParam(shader, kernelIndex, Fsr2ShaderIDs.SrvInputColor, context.source);
cmd.SetComputeTextureParam(shader, kernelIndex, Fsr2ShaderIDs.UavAutoReactive, _reactiveMask);
cmd.SetComputeConstantBufferParam(shader, Fsr2ShaderIDs.CbGenReactive, _reactiveMaskConstants, 0, Marshal.SizeOf<GenerateReactiveConstants>());
cmd.DispatchCompute(shader, kernelIndex, dispatchX, dispatchY, 1);
cmd.EndSample("Generate Reactive Mask");
return _reactiveMask;
}
[Serializable, StructLayout(LayoutKind.Sequential)]
internal struct GenerateReactiveConstants
{
public float scale;
public float threshold;
public float binaryValue;
public uint flags;
}
private ConstantsBuffer<CasConstants> _sharpeningConstants;
private static readonly int CasInputColor = Shader.PropertyToID("r_input_color");
private static readonly int CasOutputColor = Shader.PropertyToID("rw_output_color");
private static readonly int CasConstantBuffer = Shader.PropertyToID("cbCAS");
/// <summary>
/// Generalized standalone version of the CAS sharpening filter that can be applied after any non-FSR upscaling technique.
/// </summary>
protected void ApplySharpening(CommandBuffer cmd, PostProcessRenderContext context, in Vector2Int imageSize, float sharpness, RenderTargetIdentifier input, RenderTargetIdentifier output)
{
ComputeShader shader = context.resources.computeShaders.casSharpening;
if (shader == null)
{
cmd.CopyTexture(input, output);
return;
}
const int threadGroupWorkRegionDimRcas = 16;
int threadGroupsX = (imageSize.x + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
int threadGroupsY = (imageSize.y + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
cmd.BeginSample("CAS Sharpening");
// Compute the constants
_sharpeningConstants ??= ConstantsBuffer<CasConstants>.Create();
int sharpnessIndex = Mathf.RoundToInt(Mathf.Clamp01(sharpness) * (CasConfigs.Length - 1));
_sharpeningConstants.Value = CasConfigs[sharpnessIndex];
_sharpeningConstants.UpdateBufferData(cmd);
// Dispatch CAS
int kernelIndex = shader.FindKernel("CS");
cmd.SetComputeTextureParam(shader, kernelIndex, CasInputColor, input);
cmd.SetComputeTextureParam(shader, kernelIndex, CasOutputColor, output);
cmd.SetComputeConstantBufferParam(shader, CasConstantBuffer, _sharpeningConstants, 0, Marshal.SizeOf<CasConstants>());
cmd.DispatchCompute(shader, kernelIndex, threadGroupsX, threadGroupsY, 1);
cmd.EndSample("CAS Sharpening");
}
[Serializable, StructLayout(LayoutKind.Sequential)]
private struct CasConstants
{
public CasConstants(uint sharpness, uint halfSharp)
{
// Since we don't use CAS for scaling, most of these values end up being constants
scaling0 = scaling1 = 1065353216;
scaling2 = scaling3 = 0;
sharpness0 = sharpness;
sharpness1 = halfSharp;
sharpness2 = 1090519040;
sharpness3 = 0;
}
public readonly uint scaling0;
public readonly uint scaling1;
public readonly uint scaling2;
public readonly uint scaling3;
public readonly uint sharpness0;
public readonly uint sharpness1;
public readonly uint sharpness2;
public readonly uint sharpness3;
}
/// <summary>
/// The FidelityFX C++ codebase uses floats bitwise converted to ints to pass sharpness parameters to the CAS shader.
/// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values.
/// </summary>
private static readonly CasConstants[] CasConfigs =
{
new(3187671040u, 45056u),
new(3187831332u, 45075u),
new(3187997869u, 45095u),
new(3188171023u, 45117u),
new(3188351197u, 45139u),
new(3188538827u, 45161u),
new(3188734385u, 45185u),
new(3188938384u, 45210u),
new(3189151382u, 45236u),
new(3189373991u, 45263u),
new(3189606873u, 45292u),
new(3189850757u, 45322u),
new(3190106443u, 45353u),
new(3190374807u, 45386u),
new(3190656816u, 45420u),
new(3190953540u, 45456u),
new(3191266159u, 45494u),
new(3191595985u, 45535u),
new(3191944482u, 45577u),
new(3192313280u, 45622u),
new(3192704205u, 45670u),
};
protected bool CreateRenderTexture(ref RenderTexture rt, string name, in Vector2Int size, GraphicsFormat format, bool enableRandomWrite = false)
{
rt = new RenderTexture(size.x, size.y, 0, format) { name = name, enableRandomWrite = enableRandomWrite };
return rt.Create();
}
protected bool CreateRenderTexture(ref RenderTexture rt, string name, in Vector2Int size, RenderTextureFormat format, bool enableRandomWrite = false)
{
rt = new RenderTexture(size.x, size.y, 0, format) { name = name, enableRandomWrite = enableRandomWrite };
return rt.Create();
}
protected void DestroyRenderTexture(ref RenderTexture rt)
{
if (rt == null)
return;
rt.Release();
rt = null;
}
protected void DestroyConstantsBuffer<TConst>(ref ConstantsBuffer<TConst> cb)
where TConst: struct
{
if (cb == null)
return;
cb.Destroy();
cb = null;
}
}
}

2
Packages/fidelityfx.fsr

@ -1 +1 @@
Subproject commit d65cc3a35de270a1011c8158810e3d56c579953f
Subproject commit f5ad1705907334634466433dbaa1a8633fa53a39
Loading…
Cancel
Save