diff --git a/Assets/Resources/FSR2/ffx_fsr2_compute_luminance_pyramid_pass.compute b/Assets/Resources/FSR2/ffx_fsr2_compute_luminance_pyramid_pass.compute index 2cdf974..5c1d47c 100644 --- a/Assets/Resources/FSR2/ffx_fsr2_compute_luminance_pyramid_pass.compute +++ b/Assets/Resources/FSR2/ffx_fsr2_compute_luminance_pyramid_pass.compute @@ -2,6 +2,6 @@ #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 +#define SPD_NO_WAVE_OPERATIONS // Wave operations require shader model 6.0; this works with #pragma use_dxc but only on D3D12 #include "shaders/ffx_fsr2_compute_luminance_pyramid_pass.hlsl" diff --git a/Assets/Scripts/FSR2Thing.cs b/Assets/Scripts/FSR2Thing.cs index a3ee6e6..98f2ec9 100644 --- a/Assets/Scripts/FSR2Thing.cs +++ b/Assets/Scripts/FSR2Thing.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; +using FidelityFX; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; @@ -24,6 +25,8 @@ public class FSR2Thing : MonoBehaviour [HideInInspector] public float renderScale; + public Fsr2Callbacks callbacks; + private RenderTexture _upscaleRT; private RenderTexture _rcasOutput; private Texture2D _exposure; @@ -35,7 +38,7 @@ public class FSR2Thing : MonoBehaviour { if (_testMaterial == null) { - var testShader = Shader.Find("FSR2/FSRTest"); + var testShader = callbacks.LoadShader("FSR2/FSRTest"); _testMaterial = new Material(testShader); } @@ -50,9 +53,7 @@ public class FSR2Thing : MonoBehaviour { if (_rcasComputeShader == null) { - // TODO: this is nasty, I don't like this. How do we manage/bind compute shaders best? => make a Callbacks class/interface with overridable implementation - // GPUInstancer used Resources, we modified that to load stuff from asset bundles instead. Maybe provide a custom loader callback interface? - _rcasComputeShader = Resources.Load("FSR2/ffx_fsr2_rcas_pass"); + _rcasComputeShader = callbacks.LoadComputeShader("FSR2/ffx_fsr2_rcas_pass"); } return _rcasComputeShader; @@ -61,6 +62,9 @@ public class FSR2Thing : MonoBehaviour private ComputeBuffer _fsr2ConstantsBuffer; private readonly Fsr2Constants[] _fsr2ConstantsArray = { new Fsr2Constants() }; + + private ComputeBuffer _spdConstantsBuffer; + private readonly SpdConstants[] _spdConstantsArray = { new SpdConstants() }; private ComputeBuffer _rcasConstantsBuffer; private readonly RcasConstants[] _rcasConstantsArray = new RcasConstants[1]; @@ -82,6 +86,7 @@ public class FSR2Thing : MonoBehaviour _exposure.Apply(); _fsr2ConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); + _spdConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); _rcasConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); } @@ -93,6 +98,12 @@ public class FSR2Thing : MonoBehaviour _rcasConstantsBuffer = null; } + if (_spdConstantsBuffer != null) + { + _spdConstantsBuffer.Release(); + _spdConstantsBuffer = null; + } + if (_fsr2ConstantsBuffer != null) { _fsr2ConstantsBuffer.Release(); @@ -207,6 +218,15 @@ public class FSR2Thing : MonoBehaviour public float lumaMipRcp; } + [Serializable, StructLayout(LayoutKind.Sequential)] + private struct SpdConstants + { + public uint mips; + public uint numWorkGroups; + public uint workGroupOffsetX, workGroupOffsetY; + public uint renderSizeX, renderSizeY; + } + private static readonly List RcasConfigs = new() { new(1048576000u, 872428544u), diff --git a/Assets/Scripts/Fsr2Callbacks.cs b/Assets/Scripts/Fsr2Callbacks.cs new file mode 100644 index 0000000..b4a6272 --- /dev/null +++ b/Assets/Scripts/Fsr2Callbacks.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +namespace FidelityFX +{ + public class Fsr2Callbacks + { + public virtual Shader LoadShader(string name) + { +#if UNITY_EDITOR + return Shader.Find(name); +#else + return Resources.Load(name); +#endif + } + + public virtual ComputeShader LoadComputeShader(string name) + { + return Resources.Load(name); + } + + public virtual void ApplyMipmapBias(float biasOffset) + { + foreach (var texture in Resources.FindObjectsOfTypeAll()) + { + texture.mipMapBias += biasOffset; + } + } + } +} diff --git a/Assets/Scripts/Fsr2Callbacks.cs.meta b/Assets/Scripts/Fsr2Callbacks.cs.meta new file mode 100644 index 0000000..abc4d96 --- /dev/null +++ b/Assets/Scripts/Fsr2Callbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5906deeb6ec2854449bf33db2e71a046 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SubsampleTest.cs b/Assets/Scripts/SubsampleTest.cs index 6043e2c..47d9ddb 100644 --- a/Assets/Scripts/SubsampleTest.cs +++ b/Assets/Scripts/SubsampleTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using FidelityFX; using UnityEngine; [RequireComponent(typeof(Camera))] @@ -17,6 +18,8 @@ public class SubsampleTest : MonoBehaviour [SerializeField] private bool enableJitter; + private Fsr2Callbacks callbacks = new Fsr2Callbacks(); + private FSR2Thing fsr2Thing; private void OnEnable() @@ -33,6 +36,7 @@ public class SubsampleTest : MonoBehaviour outputCamera.eventMask = 0; fsr2Thing = outputCameraObject.AddComponent(); + fsr2Thing.callbacks = callbacks; fsr2Thing.gameCamera = gameCamera; fsr2Thing.outputCamera = outputCamera; fsr2Thing.renderScale = renderScale; @@ -60,21 +64,14 @@ public class SubsampleTest : MonoBehaviour // Adjust texture mipmap LOD bias by log2(renderResolution/displayResolution) - 1.0; // May need to leave this to the game dev, as we don't know which textures do and don't belong to the 3D scene - // TODO: add to Callbacks class/interface (ApplyMipmapBias) float biasOffset = GetMipmapBiasOffset(); - foreach (var tex in Resources.FindObjectsOfTypeAll()) - { - tex.mipMapBias += biasOffset; - } + callbacks.ApplyMipmapBias(biasOffset); } private void OnDisable() { float biasOffset = GetMipmapBiasOffset(); - foreach (var tex in Resources.FindObjectsOfTypeAll()) - { - tex.mipMapBias -= biasOffset; - } + callbacks.ApplyMipmapBias(-biasOffset); gameCamera.targetTexture.Release(); gameCamera.targetTexture = null;