From d71b061d16a02035173ba5b57968c482ad028d26 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Sat, 22 Mar 2025 16:08:39 +0100 Subject: [PATCH] Added new shader IDs and resource definitions --- .../Upscaling/ASR/Runtime/AsrResources.cs | 51 +++++++++++++++---- .../Upscaling/ASR/Runtime/AsrShaderIDs.cs | 15 ++++++ 2 files changed, 56 insertions(+), 10 deletions(-) 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 a879238..5fedade 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 @@ -41,9 +41,10 @@ namespace ArmASR public readonly RenderTexture[] DilatedMotionVectors = new RenderTexture[2]; public readonly RenderTexture[] LockStatus = new RenderTexture[2]; public readonly RenderTexture[] InternalUpscaled = new RenderTexture[2]; + public readonly RenderTexture[] InternalReactive = new RenderTexture[2]; public readonly RenderTexture[] LumaHistory = new RenderTexture[2]; - public void Create(Asr.ContextDescription contextDescription) + public void Create(in Asr.ContextDescription contextDescription) { // Generate the data for the LUT const int lanczos2LutWidth = 128; @@ -61,6 +62,8 @@ namespace ArmASR maximumBias[i] = MaximumBias[i] / 2.0f; } + GetFormatRequirements(contextDescription, out bool isBalancedOrPerformance, out bool preparedInputColorNeedsFp16, out GraphicsFormat r8Format, out GraphicsFormat r16Format, out GraphicsFormat rg16Format); + // Resource FSR2_LanczosLutData: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE // R16_SNorm textures are not supported by Unity on most platforms, strangely enough. So instead we use R32_SFloat and upload pre-normalized float data. LanczosLut = new Texture2D(lanczos2LutWidth, 1, GraphicsFormat.R32_SFloat, TextureCreationFlags.None) { name = "ASR_LanczosLutData" }; @@ -88,14 +91,14 @@ namespace ArmASR SpdAtomicCounter.Create(); // Resource FSR2_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE - AutoExposure = new RenderTexture(1, 1, 0, GraphicsFormat.R32G32_SFloat) { name = "ASR_AutoExposure", enableRandomWrite = true }; + AutoExposure = new RenderTexture(1, 1, 0, rg16Format) { name = "ASR_AutoExposure", enableRandomWrite = true }; AutoExposure.Create(); // Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE // This is a rather special case: it's an aliasable resource, but because we require a mipmap chain and bind specific mip levels per shader, we can't easily use temporary RTs for this. int w = contextDescription.MaxRenderSize.x / 2, h = contextDescription.MaxRenderSize.y / 2; int mipCount = 1 + Mathf.FloorToInt(Mathf.Log(Math.Max(w, h), 2.0f)); - SceneLuminance = new RenderTexture(w, h, 0, GraphicsFormat.R16_SFloat, mipCount) { name = "ASR_ExposureMips", enableRandomWrite = true, useMipMap = true, autoGenerateMips = false }; + SceneLuminance = new RenderTexture(w, h, 0, r16Format, mipCount) { name = "ASR_ExposureMips", enableRandomWrite = true, useMipMap = true, autoGenerateMips = false }; SceneLuminance.Create(); // Resources FSR2_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE @@ -105,18 +108,29 @@ namespace ArmASR CreateDoubleBufferedResource(LockStatus, "ASR_LockStatus", contextDescription.DisplaySize, GraphicsFormat.R16G16_SFloat); // Resources FSR2_InternalUpscaled1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_NONE - CreateDoubleBufferedResource(InternalUpscaled, "ASR_InternalUpscaled", contextDescription.DisplaySize, GraphicsFormat.R16G16B16A16_SFloat); - - // Resources FSR2_LumaHistory1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, FFX_RESOURCE_FLAGS_NONE - CreateDoubleBufferedResource(LumaHistory, "ASR_LumaHistory", contextDescription.DisplaySize, GraphicsFormat.R8G8B8A8_UNorm); + CreateDoubleBufferedResource(InternalUpscaled, "ASR_InternalUpscaled", contextDescription.DisplaySize, !isBalancedOrPerformance ? GraphicsFormat.R16G16B16A16_SFloat : GraphicsFormat.B10G11R11_UFloatPack32); + + // Additional textures used by either balanced or performance presets + if (isBalancedOrPerformance) + { + // Resources FSR2_InternalReactive1/2: FFXM_RESOURCE_USAGE_RENDERTARGET, FFXM_SURFACE_FORMAT_R8_SNORM, FFXM_RESOURCE_FLAGS_NONE + CreateDoubleBufferedResource(InternalReactive, "ASR_InternalReactive", contextDescription.DisplaySize, GraphicsFormat.R8_SNorm); // TODO: R8_SNorm *might* be a problem? + } + else // Quality preset specific + { + // Resources FSR2_LumaHistory1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, FFX_RESOURCE_FLAGS_NONE + CreateDoubleBufferedResource(LumaHistory, "ASR_LumaHistory", contextDescription.DisplaySize, GraphicsFormat.R8G8B8A8_UNorm); + } } // Set up shared aliasable resources, i.e. temporary render textures // These do not need to persist between frames, but they do need to be available between passes - public static void CreateAliasableResources(CommandBuffer commandBuffer, Asr.ContextDescription contextDescription, Asr.DispatchDescription dispatchParams) + public static void CreateAliasableResources(CommandBuffer commandBuffer, in Asr.ContextDescription contextDescription, in Asr.DispatchDescription dispatchParams) { Vector2Int displaySize = contextDescription.DisplaySize; Vector2Int maxRenderSize = contextDescription.MaxRenderSize; + + GetFormatRequirements(contextDescription, out bool isBalancedOrPerformance, out bool preparedInputColorNeedsFp16, out GraphicsFormat r8Format, out GraphicsFormat r16Format, out GraphicsFormat rg16Format); // FSR2_ReconstructedPrevNearestDepth: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE commandBuffer.GetTemporaryRT(AsrShaderIDs.UavReconstructedPrevNearestDepth, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R32_UInt, 1, true); @@ -131,10 +145,26 @@ namespace ArmASR commandBuffer.GetTemporaryRT(AsrShaderIDs.UavDilatedReactiveMasks, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R8G8_UNorm, 1, true); // FSR2_PreparedInputColor: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE - commandBuffer.GetTemporaryRT(AsrShaderIDs.UavPreparedInputColor, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R16G16B16A16_SFloat, 1, true); + commandBuffer.GetTemporaryRT(AsrShaderIDs.UavPreparedInputColor, maxRenderSize.x, maxRenderSize.y, 0, default, preparedInputColorNeedsFp16 ? GraphicsFormat.R16G16B16A16_SFloat : GraphicsFormat.R8G8B8A8_UNorm, 1, true); // FSR2_NewLocks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE - commandBuffer.GetTemporaryRT(AsrShaderIDs.UavNewLocks, displaySize.x, displaySize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true); + commandBuffer.GetTemporaryRT(AsrShaderIDs.UavNewLocks, displaySize.x, displaySize.y, 0, default, r8Format, 1, true); + } + + private static void GetFormatRequirements(in Asr.ContextDescription contextDescription, + out bool isBalancedOrPerformance, out bool preparedInputColorNeedsFP16, + out GraphicsFormat r8Format, out GraphicsFormat r16Format, out GraphicsFormat rg16Format) + { + bool applyPerfModeOptimizations = contextDescription.Variant == Asr.Variant.Performance; + bool applyBalancedModeOptimizations = contextDescription.Variant == Asr.Variant.Balanced; + isBalancedOrPerformance = applyBalancedModeOptimizations || applyPerfModeOptimizations; + preparedInputColorNeedsFP16 = !applyPerfModeOptimizations; + + // OpenGLES 3.2 specific: We need to work around some GLES limitations for some resources. + bool isOpenGLES = SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3; + r8Format = isOpenGLES ? GraphicsFormat.R32_SFloat : GraphicsFormat.R8_UNorm; + r16Format = isOpenGLES ? GraphicsFormat.R32_SFloat : GraphicsFormat.R16_SFloat; + rg16Format = isOpenGLES ? GraphicsFormat.R16G16B16A16_SFloat : GraphicsFormat.R16G16_SFloat; } public static void DestroyAliasableResources(CommandBuffer commandBuffer) @@ -160,6 +190,7 @@ namespace ArmASR public void Destroy() { DestroyResource(LumaHistory); + DestroyResource(InternalReactive); DestroyResource(InternalUpscaled); DestroyResource(LockStatus); DestroyResource(DilatedMotionVectors); diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs index 8f829bb..64af0eb 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs @@ -38,7 +38,9 @@ namespace ArmASR public static readonly int SrvPrevDilatedMotionVectors = Shader.PropertyToID("r_previous_dilated_motion_vectors"); public static readonly int SrvDilatedDepth = Shader.PropertyToID("r_dilatedDepth"); public static readonly int SrvInternalUpscaled = Shader.PropertyToID("r_internal_upscaled_color"); + public static readonly int SrvInternalTemporalReactive = Shader.PropertyToID("r_internal_temporal_reactive"); public static readonly int SrvLockStatus = Shader.PropertyToID("r_lock_status"); + public static readonly int SrvNewLocks = Shader.PropertyToID("r_new_locks"); public static readonly int SrvLockInputLuma = Shader.PropertyToID("r_lock_input_luma"); public static readonly int SrvPreparedInputColor = Shader.PropertyToID("r_prepared_input_color"); public static readonly int SrvLumaHistory = Shader.PropertyToID("r_luma_history"); @@ -65,6 +67,19 @@ namespace ArmASR public static readonly int UavAutoExposure = Shader.PropertyToID("rw_auto_exposure"); public static readonly int UavSpdAtomicCount = Shader.PropertyToID("rw_spd_global_atomic"); public static readonly int UavAutoReactive = Shader.PropertyToID("rw_output_autoreactive"); + + // Render textures, i.e. output targets for fragment shaders + public static readonly int RtInternalUpscalerColor = Shader.PropertyToID("rw_internal_upscaled_color"); + public static readonly int RtInternalTemporalReactive = Shader.PropertyToID("rw_internal_temporal_reactive"); + public static readonly int RtLockStatus = Shader.PropertyToID("rw_lock_status"); + public static readonly int RtLumaHistory = Shader.PropertyToID("rw_luma_history"); + public static readonly int RtUpscaledOutput = Shader.PropertyToID("rw_upscaled_output"); + public static readonly int RtDilatedReactiveMasks = Shader.PropertyToID("rw_dilated_reactive_masks"); + public static readonly int RtPreparedInputColor = Shader.PropertyToID("rw_prepared_input_color"); + public static readonly int RtDilatedMotionVectors = Shader.PropertyToID("rw_dilated_motion_vectors"); + public static readonly int RtDilatedDepth = Shader.PropertyToID("rw_dilatedDepth"); + public static readonly int RtLockInputLuma = Shader.PropertyToID("rw_lock_input_luma"); + public static readonly int RtAutoReactive = Shader.PropertyToID("rw_output_autoreactive"); // Constant buffer bindings public static readonly int CbFsr2 = Shader.PropertyToID("cbFSR2");