From dd33e77b6f1a35e6bd9791b4cfd359ddcf22aba0 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Fri, 21 Mar 2025 22:39:34 +0100 Subject: [PATCH] Reworked ASR passes to allow for blitting using fragment shaders, and got an idea of the problems yet to solve. Modified assets script and added it to the PPV2 resources. Some additional refactoring and bug fixing as well. --- .../PostProcessing/PostProcessResources.asset | 4 + .../Effects/Upscaling/ASR/Runtime/Asr.cs | 44 +++- .../Upscaling/ASR/Runtime/AsrAssets.cs | 66 ++---- .../Upscaling/ASR/Runtime/AsrContext.cs | 4 +- .../Effects/Upscaling/ASR/Runtime/AsrPass.cs | 213 ++++++++++-------- .../Upscaling/ASR/Runtime/AsrResources.cs | 12 +- .../Runtime/PostProcessResources.cs | 6 + 7 files changed, 195 insertions(+), 154 deletions(-) diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/PostProcessResources.asset b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/PostProcessResources.asset index 954f3a9..36cc0e2 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/PostProcessResources.asset +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/PostProcessResources.asset @@ -159,3 +159,7 @@ MonoBehaviour: convert: {fileID: 7200000, guid: a41757aacd8b70e42a4001d514bfbe53, type: 3} activate: {fileID: 7200000, guid: d7de362950af6fe4e90da7d6e32f9826, type: 3} upscale: {fileID: 7200000, guid: 5d28d29787492b74aa736a21f70572c7, type: 3} + asrUpscalerShaders: + fragmentShader: {fileID: 4800000, guid: 147cc2cffac69ef4eb3ea8addafc9d10, type: 3} + computeLuminancePyramidPass: {fileID: 7200000, guid: 57220d870cb441c8a6df8a9e15a74283, type: 3} + lockPass: {fileID: 7200000, guid: a6e1d5d5372d467790fcf2d089b50ef7, type: 3} diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs index a75fab0..590f5f2 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs @@ -21,6 +21,7 @@ using System; using System.Runtime.InteropServices; using UnityEngine; +using UnityEngine.Rendering; namespace ArmASR { @@ -133,6 +134,45 @@ namespace ArmASR } #endif + /// + /// Alternative for CommandBuffer.SetComputeTextureParam that guards against attempts to bind mip levels that don't exist. + /// + internal static void SetComputeTextureMipParam(this CommandBuffer commandBuffer, ComputeShader computeShader, int kernelIndex, int nameID, Texture texture, int mipLevel) + { + mipLevel = Math.Min(mipLevel, texture.mipmapCount - 1); + commandBuffer.SetComputeTextureParam(computeShader, kernelIndex, nameID, texture, mipLevel); + } + + internal static void SetComputeResourceParam(this CommandBuffer commandBuffer, ComputeShader computeShader, int kernelIndex, int nameID, in ResourceView resource) + { + commandBuffer.SetComputeTextureParam(computeShader, kernelIndex, nameID, resource.RenderTarget, resource.MipLevel, resource.SubElement); + } + + internal static void SetComputeConstantBufferParam(this CommandBuffer commandBuffer, ComputeShader computeShader, int nameID, ComputeBuffer buffer) + { + commandBuffer.SetComputeConstantBufferParam(computeShader, nameID, buffer, 0, buffer.stride); + } + + internal static void SetGlobalResource(this CommandBuffer commandBuffer, int nameID, in ResourceView resource) + { + commandBuffer.SetGlobalTexture(nameID, resource.RenderTarget, resource.SubElement); + } + + internal static void DestroyObject(UnityEngine.Object obj) + { + if (obj == null) + return; + +#if UNITY_EDITOR + if (Application.isPlaying && !UnityEditor.EditorApplication.isPaused) + UnityEngine.Object.Destroy(obj); + else + UnityEngine.Object.DestroyImmediate(obj); +#else + UnityEngine.Object.Destroy(obj); +#endif + } + public enum QualityMode { NativeAA = 0, @@ -171,7 +211,7 @@ namespace ArmASR /// /// A structure encapsulating the parameters for dispatching the various passes of FidelityFX Super Resolution 2. /// - public class DispatchDescription + public class DispatchDescription // TODO: make into struct { public ResourceView Color; public ResourceView Depth; @@ -199,7 +239,7 @@ namespace ArmASR /// /// A structure encapsulating the parameters for automatic generation of a reactive mask. /// - public class GenerateReactiveDescription + public class GenerateReactiveDescription // TODO: make into struct (with static readonly Default property) { public ResourceView ColorOpaqueOnly; public ResourceView ColorPreUpscale; diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs index 95ff401..b44859c 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs @@ -36,17 +36,22 @@ namespace ArmASR { shaders = new AsrShaders { + fragmentShader = FindFragmentShader("ffxm_fsr2_fs"), computeLuminancePyramidPass = FindComputeShader("ffxm_fsr2_compute_luminance_pyramid_pass"), - reconstructPreviousDepthPass = FindComputeShader("ffx_fsr2_reconstruct_previous_depth_pass"), - depthClipPass = FindComputeShader("ffx_fsr2_depth_clip_pass"), lockPass = FindComputeShader("ffxm_fsr2_lock_pass"), - accumulatePass = FindComputeShader("ffx_fsr2_accumulate_pass"), - sharpenPass = FindComputeShader("ffx_fsr2_rcas_pass"), - autoGenReactivePass = FindComputeShader("ffx_fsr2_autogen_reactive_pass"), - tcrAutoGenPass = FindComputeShader("ffx_fsr2_tcr_autogen_pass"), }; } + private static Shader FindFragmentShader(string name) + { + string[] assetGuids = UnityEditor.AssetDatabase.FindAssets($"t:Shader {name}"); + if (assetGuids == null || assetGuids.Length == 0) + return null; + + string assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(assetGuids[0]); + return UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath); + } + private static ComputeShader FindComputeShader(string name) { string[] assetGuids = UnityEditor.AssetDatabase.FindAssets($"t:ComputeShader {name}"); @@ -66,44 +71,19 @@ namespace ArmASR public class AsrShaders { /// - /// The compute shader used by the luminance pyramid computation pass. + /// Combined shader file containing all non-compute passes. /// - public ComputeShader computeLuminancePyramidPass; - - /// - /// The compute shader used by the previous depth reconstruction pass. - /// - public ComputeShader reconstructPreviousDepthPass; - + public Shader fragmentShader; + /// - /// The compute shader used by the depth clip pass. + /// The compute shader used by the luminance pyramid computation pass. /// - public ComputeShader depthClipPass; + public ComputeShader computeLuminancePyramidPass; /// /// The compute shader used by the lock pass. /// public ComputeShader lockPass; - - /// - /// The compute shader used by the accumulation pass. - /// - public ComputeShader accumulatePass; - - /// - /// The compute shader used by the RCAS sharpening pass. - /// - public ComputeShader sharpenPass; - - /// - /// The compute shader used to auto-generate a reactive mask. - /// - public ComputeShader autoGenReactivePass; - - /// - /// The compute shader used to auto-generate a transparency & composition mask. - /// - public ComputeShader tcrAutoGenPass; /// /// Returns a copy of this class and its contents. @@ -122,14 +102,9 @@ namespace ArmASR { return new AsrShaders { + fragmentShader = Object.Instantiate(fragmentShader), computeLuminancePyramidPass = Object.Instantiate(computeLuminancePyramidPass), - reconstructPreviousDepthPass = Object.Instantiate(reconstructPreviousDepthPass), - depthClipPass = Object.Instantiate(depthClipPass), lockPass = Object.Instantiate(lockPass), - accumulatePass = Object.Instantiate(accumulatePass), - sharpenPass = Object.Instantiate(sharpenPass), - autoGenReactivePass = Object.Instantiate(autoGenReactivePass), - tcrAutoGenPass = Object.Instantiate(tcrAutoGenPass), }; } @@ -139,14 +114,9 @@ namespace ArmASR /// public void Dispose() { + Object.Destroy(fragmentShader); Object.Destroy(computeLuminancePyramidPass); - Object.Destroy(reconstructPreviousDepthPass); - Object.Destroy(depthClipPass); Object.Destroy(lockPass); - Object.Destroy(accumulatePass); - Object.Destroy(sharpenPass); - Object.Destroy(autoGenReactivePass); - Object.Destroy(tcrAutoGenPass); } } } diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs index f16f150..4175bbe 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs @@ -229,8 +229,8 @@ namespace ArmASR // Dispatch RCAS const int threadGroupWorkRegionDimRcas = 16; - int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; - int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; + int threadGroupsX = (_contextDescription.DisplaySize.x + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; + int threadGroupsY = (_contextDescription.DisplaySize.y + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; _sharpenPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY); } diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs index 5582f6d..a166814 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs @@ -19,6 +19,7 @@ // THE SOFTWARE. using System; +using System.Collections.Generic; using System.Diagnostics; using UnityEngine; using UnityEngine.Profiling; @@ -41,6 +42,11 @@ namespace ArmASR protected ComputeShader ComputeShader; protected int KernelIndex; + + protected Material FragmentMaterial; + protected int FragmentPass; + protected MaterialPropertyBlock FragmentProperties; + protected readonly List FragmentKeywords = new(); private CustomSampler _sampler; @@ -53,6 +59,13 @@ namespace ArmASR public virtual void Dispose() { + if (FragmentMaterial != null) + { + Asr.DestroyObject(FragmentMaterial); + FragmentMaterial = null; + } + + FragmentKeywords.Clear(); } public void ScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) @@ -80,6 +93,45 @@ namespace ArmASR KernelIndex = ComputeShader.FindKernel("main"); _sampler = CustomSampler.Create(passName); + foreach (string keyword in GetKeywords(flags)) + { + ComputeShader.EnableKeyword(keyword); + } + } + + protected void InitFragmentShader(string passName, Shader shader, int passNumber) + { + InitFragmentShader(passName, shader, passNumber, ContextDescription.Flags); + } + + private void InitFragmentShader(string passName, Shader shader, int passNumber, Asr.InitializationFlags flags) + { + if (shader == null) + { + throw new MissingReferenceException($"Shader for ASR pass '{passName}' could not be loaded! Please ensure it is included in the project correctly."); + } + + FragmentMaterial = new Material(shader); + FragmentPass = passNumber; + _sampler = CustomSampler.Create(passName); + + FragmentProperties = new MaterialPropertyBlock(); + foreach (string keyword in GetKeywords(flags)) + { + // TODO: also want to include keywords that should be disabled (false) + // TODO: might be better to just determine all the keywords once up front and set them globally, probably don't even need to manage them here but in the AsrContext instead + // NOTE: be mindful of UNITY_2021_2_OR_NEWER (Local & GlobalKeyword were introduced there) + FragmentKeywords.Add(new LocalKeyword(shader, keyword)); + } + } + + protected void BlitFragment(CommandBuffer commandBuffer) + { + commandBuffer.DrawProcedural(Matrix4x4.identity, FragmentMaterial, FragmentPass, MeshTopology.Triangles, 3, 1, FragmentProperties); + } + + private static IEnumerable GetKeywords(Asr.InitializationFlags flags) + { bool useLut = false; #if UNITY_2022_1_OR_NEWER // This will also work in 2020.3.43+ and 2021.3.14+ if (SystemInfo.computeSubGroupSize == 64) @@ -89,12 +141,12 @@ namespace ArmASR #endif // This matches the permutation rules from the CreatePipeline* functions - if ((flags & Asr.InitializationFlags.EnableHighDynamicRange) != 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_HDR_COLOR_INPUT"); - if ((flags & Asr.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS"); - if ((flags & Asr.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_JITTERED_MOTION_VECTORS"); - if ((flags & Asr.InitializationFlags.EnableDepthInverted) != 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_INVERTED_DEPTH"); - if (useLut) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE"); - if ((flags & Asr.InitializationFlags.EnableFP16Usage) != 0) ComputeShader.EnableKeyword("FFXM_HALF"); + if ((flags & Asr.InitializationFlags.EnableHighDynamicRange) != 0) yield return "FFXM_FSR2_OPTION_HDR_COLOR_INPUT"; + if ((flags & Asr.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) yield return "FFXM_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS"; + if ((flags & Asr.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0) yield return "FFXM_FSR2_OPTION_JITTERED_MOTION_VECTORS"; + if ((flags & Asr.InitializationFlags.EnableDepthInverted) != 0) yield return "FFXM_FSR2_OPTION_INVERTED_DEPTH"; + if (useLut) yield return "FFXM_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE"; + if ((flags & Asr.InitializationFlags.EnableFP16Usage) != 0) yield return "FFXM_HALF"; } [Conditional("ENABLE_PROFILER")] @@ -124,8 +176,7 @@ namespace ArmASR protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - ref var color = ref dispatchParams.Color; - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeResourceParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, dispatchParams.Color); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavSpdAtomicCount, Resources.SpdAtomicCounter); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel); @@ -144,26 +195,21 @@ namespace ArmASR public AsrReconstructPreviousDepthPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { - InitComputeShader("Reconstruct & Dilate", contextDescription.Shaders.reconstructPreviousDepthPass); + InitFragmentShader("Reconstruct & Dilate", contextDescription.Shaders.fragmentShader, 1); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - ref var color = ref dispatchParams.Color; - ref var depth = ref dispatchParams.Depth; - ref var motionVectors = ref dispatchParams.MotionVectors; - ref var exposure = ref dispatchParams.Exposure; + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputColor, dispatchParams.Color); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputDepth, dispatchParams.Depth); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputExposure, dispatchParams.Exposure); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); - - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); + // TODO: this actually needs to be the render target + commandBuffer.SetGlobalTexture(AsrShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); - commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); - - commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); + FragmentProperties.SetConstantBuffer(AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); + BlitFragment(commandBuffer); } } @@ -172,33 +218,25 @@ namespace ArmASR public AsrDepthClipPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { - InitComputeShader("Depth Clip", contextDescription.Shaders.depthClipPass); + InitFragmentShader("Depth Clip", contextDescription.Shaders.fragmentShader, 2); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - 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, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvReactiveMask, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvTransparencyAndCompositionMask, tac.RenderTarget, tac.MipLevel, tac.SubElement); - - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvReconstructedPrevNearestDepth, AsrShaderIDs.UavReconstructedPrevNearestDepth); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedDepth, AsrShaderIDs.UavDilatedDepth); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvPrevDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex ^ 1]); - - commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); - - commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputColor, dispatchParams.Color); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputDepth, dispatchParams.Depth); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputExposure, dispatchParams.Exposure); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvReactiveMask, dispatchParams.Reactive); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvTransparencyAndCompositionMask, dispatchParams.TransparencyAndComposition); + + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvReconstructedPrevNearestDepth, AsrShaderIDs.UavReconstructedPrevNearestDepth); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvDilatedDepth, AsrShaderIDs.UavDilatedDepth); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvPrevDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex ^ 1]); + + FragmentProperties.SetConstantBuffer(AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); + BlitFragment(commandBuffer); } } @@ -230,9 +268,9 @@ namespace ArmASR public AsrAccumulatePass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants) : base(contextDescription, resources, constants) { - InitComputeShader("Reproject & Accumulate", contextDescription.Shaders.accumulatePass); + InitFragmentShader("Reproject & Accumulate", contextDescription.Shaders.fragmentShader, 3); #if UNITY_2021_2_OR_NEWER - _sharpeningKeyword = new LocalKeyword(ComputeShader, SharpeningKeyword); + _sharpeningKeyword = new LocalKeyword(ComputeShader, SharpeningKeyword); // TODO: dynamically enable this on MaterialPropertyBlock #endif } @@ -252,37 +290,35 @@ namespace ArmASR if ((ContextDescription.Flags & Asr.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) { - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); } else { - ref var motionVectors = ref dispatchParams.MotionVectors; - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputMotionVectors, dispatchParams.MotionVectors); } - ref var exposure = ref dispatchParams.Exposure; - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); - - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedReactiveMasks, AsrShaderIDs.UavDilatedReactiveMasks); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvLockStatus, Resources.LockStatus[frameIndex ^ 1]); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvPreparedInputColor, AsrShaderIDs.UavPreparedInputColor); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvLanczosLut, Resources.LanczosLut); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvUpscaleMaximumBiasLut, Resources.MaximumBiasLut); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvSceneLuminanceMips, Resources.SceneLuminance); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvAutoExposure, Resources.AutoExposure); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvLumaHistory, Resources.LumaHistory[frameIndex ^ 1]); - - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavInternalUpscaled, Resources.InternalUpscaled[frameIndex]); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavLumaHistory, Resources.LumaHistory[frameIndex]); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputExposure, dispatchParams.Exposure); + + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvDilatedReactiveMasks, AsrShaderIDs.UavDilatedReactiveMasks); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvLockStatus, Resources.LockStatus[frameIndex ^ 1]); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvPreparedInputColor, AsrShaderIDs.UavPreparedInputColor); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvLanczosLut, Resources.LanczosLut); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvUpscaleMaximumBiasLut, Resources.MaximumBiasLut); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvSceneLuminanceMips, Resources.SceneLuminance); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvAutoExposure, Resources.AutoExposure); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvLumaHistory, Resources.LumaHistory[frameIndex ^ 1]); + + // TODO: these need to be multi-render targets (and also vary depending on the ASR preset used) + commandBuffer.SetGlobalTexture(AsrShaderIDs.UavInternalUpscaled, Resources.InternalUpscaled[frameIndex]); + commandBuffer.SetGlobalTexture(AsrShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]); + commandBuffer.SetGlobalTexture(AsrShaderIDs.UavLumaHistory, Resources.LumaHistory[frameIndex]); - ref var output = ref dispatchParams.Output; - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement); + // TODO: this actually needs to be the render target + commandBuffer.SetGlobalResource(AsrShaderIDs.UavUpscaledOutput, dispatchParams.Output); - commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); - - commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); + FragmentProperties.SetConstantBuffer(AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); + BlitFragment(commandBuffer); } } @@ -295,22 +331,20 @@ namespace ArmASR { _rcasConstants = rcasConstants; - InitComputeShader("RCAS Sharpening", contextDescription.Shaders.sharpenPass); + InitFragmentShader("RCAS Sharpening", contextDescription.Shaders.fragmentShader, 4); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) { - ref var exposure = ref dispatchParams.Exposure; - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvRcasInput, Resources.InternalUpscaled[frameIndex]); + commandBuffer.SetGlobalResource(AsrShaderIDs.SrvInputExposure, dispatchParams.Exposure); + commandBuffer.SetGlobalTexture(AsrShaderIDs.SrvRcasInput, Resources.InternalUpscaled[frameIndex]); - ref var output = ref dispatchParams.Output; - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement); + // TODO: this actually needs to be the render target + commandBuffer.SetGlobalResource(AsrShaderIDs.UavUpscaledOutput, dispatchParams.Output); - commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); - commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbRcas, _rcasConstants, 0, _rcasConstants.stride); - - commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); + FragmentProperties.SetConstantBuffer(AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride); + FragmentProperties.SetConstantBuffer(AsrShaderIDs.CbRcas, _rcasConstants, 0, _rcasConstants.stride); + BlitFragment(commandBuffer); } } @@ -323,7 +357,7 @@ namespace ArmASR { _generateReactiveConstants = generateReactiveConstants; - InitComputeShader("Auto-Generate Reactive Mask", contextDescription.Shaders.autoGenReactivePass); + InitFragmentShader("Auto-Generate Reactive Mask", contextDescription.Shaders.fragmentShader, 0); } protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) @@ -334,17 +368,14 @@ namespace ArmASR { BeginSample(commandBuffer); - ref var opaqueOnly = ref dispatchParams.ColorOpaqueOnly; - ref var color = ref dispatchParams.ColorPreUpscale; - ref var reactive = ref dispatchParams.OutReactive; + commandBuffer.SetComputeResourceParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvOpaqueOnly, dispatchParams.ColorOpaqueOnly); + commandBuffer.SetComputeResourceParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, dispatchParams.ColorPreUpscale); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvOpaqueOnly, opaqueOnly.RenderTarget, opaqueOnly.MipLevel, opaqueOnly.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavAutoReactive, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement); + // TODO: this actually needs to be the render target + commandBuffer.SetComputeResourceParam(ComputeShader, KernelIndex, AsrShaderIDs.UavAutoReactive, dispatchParams.OutReactive); - commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbGenReactive, _generateReactiveConstants, 0, _generateReactiveConstants.stride); - - commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); + FragmentProperties.SetConstantBuffer(AsrShaderIDs.CbGenReactive, _generateReactiveConstants, 0, _generateReactiveConstants.stride); + BlitFragment(commandBuffer); EndSample(commandBuffer); } diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs index 44dd65a..a879238 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs @@ -173,17 +173,7 @@ namespace ArmASR private static void DestroyResource(ref Texture2D resource) { - if (resource == null) - return; - -#if UNITY_EDITOR - if (Application.isPlaying && !UnityEditor.EditorApplication.isPaused) - UnityEngine.Object.Destroy(resource); - else - UnityEngine.Object.DestroyImmediate(resource); -#else - UnityEngine.Object.Destroy(resource); -#endif + Asr.DestroyObject(resource); resource = null; } diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessResources.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessResources.cs index 8d62f44..867095e 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessResources.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessResources.cs @@ -1,4 +1,5 @@ using System; +using ArmASR; using FidelityFX.FSR2; using FidelityFX.FSR3; using UnityEngine.Serialization; @@ -292,6 +293,11 @@ namespace UnityEngine.Rendering.PostProcessing /// All the compute shaders used by post-processing. /// public ComputeShaders computeShaders; + + /// + /// Shaders used by the Arm Accuracy Super Resolution (ASR) Upscaler. + /// + public AsrShaders asrUpscalerShaders; #if UNITY_EDITOR ///