689 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			689 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | using System.Collections; | ||
|  | using System.Collections.Generic; | ||
|  | using System.Diagnostics; | ||
|  | using System.Runtime.InteropServices; | ||
|  | using UnityEditor; | ||
|  | using UnityEngine.Experimental.Rendering; | ||
|  | using UnityEngine.Rendering.RenderGraphModule; | ||
|  | 
 | ||
|  | namespace UnityEngine.Rendering.Universal | ||
|  | { | ||
|  |     class DebugHandler : IDebugDisplaySettingsQuery | ||
|  |     { | ||
|  |         #region Property Id Constants | ||
|  | 
 | ||
|  |         static readonly int k_DebugColorInvalidModePropertyId = Shader.PropertyToID("_DebugColorInvalidMode"); | ||
|  |         static readonly int k_DebugCurrentRealTimeId = Shader.PropertyToID("_DebugCurrentRealTime"); | ||
|  | 
 | ||
|  |         static readonly int k_DebugColorPropertyId = Shader.PropertyToID("_DebugColor"); | ||
|  |         static readonly int k_DebugTexturePropertyId = Shader.PropertyToID("_DebugTexture"); | ||
|  |         static readonly int k_DebugFontId = Shader.PropertyToID("_DebugFont"); | ||
|  |         static readonly int k_DebugTextureNoStereoPropertyId = Shader.PropertyToID("_DebugTextureNoStereo"); | ||
|  |         static readonly int k_DebugTextureDisplayRect = Shader.PropertyToID("_DebugTextureDisplayRect"); | ||
|  |         static readonly int k_DebugRenderTargetSupportsStereo = Shader.PropertyToID("_DebugRenderTargetSupportsStereo"); | ||
|  |         static readonly int k_DebugRenderTargetRangeRemap = Shader.PropertyToID("_DebugRenderTargetRangeRemap"); | ||
|  | 
 | ||
|  |         // Material settings... | ||
|  |         static readonly int k_DebugMaterialModeId = Shader.PropertyToID("_DebugMaterialMode"); | ||
|  |         static readonly int k_DebugVertexAttributeModeId = Shader.PropertyToID("_DebugVertexAttributeMode"); | ||
|  |         static readonly int k_DebugMaterialValidationModeId = Shader.PropertyToID("_DebugMaterialValidationMode"); | ||
|  | 
 | ||
|  |         // Rendering settings... | ||
|  |         static readonly int k_DebugMipInfoModeId = Shader.PropertyToID("_DebugMipInfoMode"); | ||
|  |         static readonly int k_DebugMipMapStatusModeId = Shader.PropertyToID("_DebugMipMapStatusMode"); | ||
|  |         static readonly int k_DebugMipMapShowStatusCodeId = Shader.PropertyToID("_DebugMipMapShowStatusCode"); | ||
|  |         static readonly int k_DebugMipMapOpacityId = Shader.PropertyToID("_DebugMipMapOpacity"); | ||
|  |         static readonly int k_DebugMipMapRecentlyUpdatedCooldownId = Shader.PropertyToID("_DebugMipMapRecentlyUpdatedCooldown"); | ||
|  |         static readonly int k_DebugMipMapTerrainTextureModeId = Shader.PropertyToID("_DebugMipMapTerrainTextureMode"); | ||
|  |         static readonly int k_DebugSceneOverrideModeId = Shader.PropertyToID("_DebugSceneOverrideMode"); | ||
|  |         static readonly int k_DebugFullScreenModeId = Shader.PropertyToID("_DebugFullScreenMode"); | ||
|  |         static readonly int k_DebugValidationModeId = Shader.PropertyToID("_DebugValidationMode"); | ||
|  |         static readonly int k_DebugValidateBelowMinThresholdColorPropertyId = Shader.PropertyToID("_DebugValidateBelowMinThresholdColor"); | ||
|  |         static readonly int k_DebugValidateAboveMaxThresholdColorPropertyId = Shader.PropertyToID("_DebugValidateAboveMaxThresholdColor"); | ||
|  |         static readonly int k_DebugMaxPixelCost = Shader.PropertyToID("_DebugMaxPixelCost"); | ||
|  | 
 | ||
|  | 
 | ||
|  |         // Lighting settings... | ||
|  |         static readonly int k_DebugLightingModeId = Shader.PropertyToID("_DebugLightingMode"); | ||
|  |         static readonly int k_DebugLightingFeatureFlagsId = Shader.PropertyToID("_DebugLightingFeatureFlags"); | ||
|  | 
 | ||
|  |         static readonly int k_DebugValidateAlbedoMinLuminanceId = Shader.PropertyToID("_DebugValidateAlbedoMinLuminance"); | ||
|  |         static readonly int k_DebugValidateAlbedoMaxLuminanceId = Shader.PropertyToID("_DebugValidateAlbedoMaxLuminance"); | ||
|  |         static readonly int k_DebugValidateAlbedoSaturationToleranceId = Shader.PropertyToID("_DebugValidateAlbedoSaturationTolerance"); | ||
|  |         static readonly int k_DebugValidateAlbedoHueToleranceId = Shader.PropertyToID("_DebugValidateAlbedoHueTolerance"); | ||
|  |         static readonly int k_DebugValidateAlbedoCompareColorId = Shader.PropertyToID("_DebugValidateAlbedoCompareColor"); | ||
|  | 
 | ||
|  |         static readonly int k_DebugValidateMetallicMinValueId = Shader.PropertyToID("_DebugValidateMetallicMinValue"); | ||
|  |         static readonly int k_DebugValidateMetallicMaxValueId = Shader.PropertyToID("_DebugValidateMetallicMaxValue"); | ||
|  | 
 | ||
|  |         static readonly int k_ValidationChannelsId = Shader.PropertyToID("_ValidationChannels"); | ||
|  |         static readonly int k_RangeMinimumId = Shader.PropertyToID("_RangeMinimum"); | ||
|  |         static readonly int k_RangeMaximumId = Shader.PropertyToID("_RangeMaximum"); | ||
|  | 
 | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Pass Data | ||
|  | 
 | ||
|  |         private static readonly ProfilingSampler s_DebugSetupSampler = new ProfilingSampler("Setup Debug Properties"); | ||
|  |         private static readonly ProfilingSampler s_DebugFinalValidationSampler = new ProfilingSampler(nameof(UpdateShaderGlobalPropertiesForFinalValidationPass)); | ||
|  | 
 | ||
|  |         DebugSetupPassData s_DebugSetupPassData = new DebugSetupPassData(); | ||
|  |         DebugFinalValidationPassData s_DebugFinalValidationPassData = new DebugFinalValidationPassData(); | ||
|  | 
 | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         readonly Material m_ReplacementMaterial; | ||
|  |         readonly Material m_HDRDebugViewMaterial; | ||
|  | 
 | ||
|  |         HDRDebugViewPass m_HDRDebugViewPass; | ||
|  |         RTHandle m_DebugScreenColorHandle; | ||
|  |         RTHandle m_DebugScreenDepthHandle; | ||
|  | 
 | ||
|  |         readonly UniversalRenderPipelineRuntimeTextures m_RuntimeTextures; | ||
|  | 
 | ||
|  |         bool m_HasDebugRenderTarget; | ||
|  |         bool m_DebugRenderTargetSupportsStereo; | ||
|  |         Vector4 m_DebugRenderTargetPixelRect; | ||
|  |         Vector4 m_DebugRenderTargetRangeRemap; | ||
|  |         RTHandle m_DebugRenderTarget; | ||
|  | 
 | ||
|  |         RTHandle m_DebugFontTexture; | ||
|  | 
 | ||
|  |         private GraphicsBuffer m_debugDisplayConstant; | ||
|  | 
 | ||
|  |         readonly UniversalRenderPipelineDebugDisplaySettings m_DebugDisplaySettings; | ||
|  | 
 | ||
|  |         DebugDisplaySettingsLighting LightingSettings => m_DebugDisplaySettings.lightingSettings; | ||
|  |         DebugDisplaySettingsMaterial MaterialSettings => m_DebugDisplaySettings.materialSettings; | ||
|  |         DebugDisplaySettingsRendering RenderingSettings => m_DebugDisplaySettings.renderingSettings; | ||
|  | 
 | ||
|  |         #region IDebugDisplaySettingsQuery | ||
|  | 
 | ||
|  |         /// <inheritdoc/> | ||
|  |         public bool AreAnySettingsActive => m_DebugDisplaySettings.AreAnySettingsActive; | ||
|  | 
 | ||
|  |         /// <inheritdoc/> | ||
|  |         public bool IsPostProcessingAllowed => m_DebugDisplaySettings.IsPostProcessingAllowed; | ||
|  | 
 | ||
|  |         /// <inheritdoc/> | ||
|  |         public bool IsLightingActive => m_DebugDisplaySettings.IsLightingActive; | ||
|  | 
 | ||
|  |         // These modes would require putting custom data into gbuffer, so instead we just disable deferred mode. | ||
|  |         internal bool IsActiveModeUnsupportedForDeferred => | ||
|  |             m_DebugDisplaySettings.lightingSettings.lightingDebugMode != DebugLightingMode.None || | ||
|  |             m_DebugDisplaySettings.lightingSettings.lightingFeatureFlags != DebugLightingFeatureFlags.None || | ||
|  |             m_DebugDisplaySettings.renderingSettings.sceneOverrideMode != DebugSceneOverrideMode.None || | ||
|  |             m_DebugDisplaySettings.materialSettings.materialDebugMode != DebugMaterialMode.None || | ||
|  |             m_DebugDisplaySettings.materialSettings.vertexAttributeDebugMode != DebugVertexAttributeMode.None || | ||
|  |             m_DebugDisplaySettings.materialSettings.materialValidationMode != DebugMaterialValidationMode.None || | ||
|  |             m_DebugDisplaySettings.renderingSettings.mipInfoMode != DebugMipInfoMode.None; | ||
|  | 
 | ||
|  |         /// <inheritdoc/> | ||
|  |         public bool TryGetScreenClearColor(ref Color color) | ||
|  |         { | ||
|  |             return m_DebugDisplaySettings.TryGetScreenClearColor(ref color); | ||
|  |         } | ||
|  | 
 | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         internal Material ReplacementMaterial => m_ReplacementMaterial; | ||
|  |         internal UniversalRenderPipelineDebugDisplaySettings DebugDisplaySettings => m_DebugDisplaySettings; | ||
|  |         internal ref RTHandle DebugScreenColorHandle => ref m_DebugScreenColorHandle; | ||
|  |         internal ref RTHandle DebugScreenDepthHandle => ref m_DebugScreenDepthHandle; | ||
|  |         internal HDRDebugViewPass hdrDebugViewPass => m_HDRDebugViewPass; | ||
|  | 
 | ||
|  |         internal bool HDRDebugViewIsActive(bool resolveFinalTarget) | ||
|  |         { | ||
|  |             // HDR debug views should only apply to the last camera in the stack | ||
|  |             return DebugDisplaySettings.lightingSettings.hdrDebugMode != HDRDebugMode.None && resolveFinalTarget; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal bool WriteToDebugScreenTexture(bool resolveFinalTarget) | ||
|  |         { | ||
|  |             return HDRDebugViewIsActive(resolveFinalTarget); | ||
|  |         } | ||
|  | 
 | ||
|  |         internal bool IsScreenClearNeeded | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 Color color = Color.black; | ||
|  | 
 | ||
|  |                 return TryGetScreenClearColor(ref color); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal bool IsRenderPassSupported | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return RenderingSettings.sceneOverrideMode == DebugSceneOverrideMode.None || RenderingSettings.sceneOverrideMode == DebugSceneOverrideMode.Overdraw; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal bool IsDepthPrimingCompatible => RenderingSettings.sceneOverrideMode != DebugSceneOverrideMode.Wireframe; | ||
|  | 
 | ||
|  |         internal int stpDebugViewIndex { get { return RenderingSettings.stpDebugViewIndex; } } | ||
|  | 
 | ||
|  |         internal DebugHandler() | ||
|  |         { | ||
|  |             m_DebugDisplaySettings = UniversalRenderPipelineDebugDisplaySettings.Instance; | ||
|  | 
 | ||
|  |             if (GraphicsSettings.TryGetRenderPipelineSettings<UniversalRenderPipelineDebugShaders>(out var shaders)) | ||
|  |             { | ||
|  |                 m_ReplacementMaterial = (shaders.debugReplacementPS != null) ? CoreUtils.CreateEngineMaterial(shaders.debugReplacementPS) : null; | ||
|  |                 m_HDRDebugViewMaterial = (shaders.hdrDebugViewPS != null) ? CoreUtils.CreateEngineMaterial(shaders.hdrDebugViewPS) : null; | ||
|  |             } | ||
|  | 
 | ||
|  |             m_HDRDebugViewPass = new HDRDebugViewPass(m_HDRDebugViewMaterial); | ||
|  | 
 | ||
|  |             m_RuntimeTextures = GraphicsSettings.GetRenderPipelineSettings<UniversalRenderPipelineRuntimeTextures>(); | ||
|  |             if (m_RuntimeTextures != null) | ||
|  |             { | ||
|  |                 m_DebugFontTexture = RTHandles.Alloc(m_RuntimeTextures.debugFontTexture); | ||
|  |             } | ||
|  | 
 | ||
|  |             m_debugDisplayConstant = new GraphicsBuffer(GraphicsBuffer.Target.Constant, 32, Marshal.SizeOf(typeof(Vector4))); | ||
|  |         } | ||
|  | 
 | ||
|  |         public void Dispose() | ||
|  |         { | ||
|  |             m_HDRDebugViewPass.Dispose(); | ||
|  |             m_DebugScreenColorHandle?.Release(); | ||
|  |             m_DebugScreenDepthHandle?.Release(); | ||
|  |             m_DebugFontTexture?.Release(); | ||
|  |             m_debugDisplayConstant.Dispose(); | ||
|  |             CoreUtils.Destroy(m_HDRDebugViewMaterial); | ||
|  |             CoreUtils.Destroy(m_ReplacementMaterial); | ||
|  |         } | ||
|  | 
 | ||
|  |         internal bool IsActiveForCamera(bool isPreviewCamera) | ||
|  |         { | ||
|  |             return !isPreviewCamera && AreAnySettingsActive; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal bool TryGetFullscreenDebugMode(out DebugFullScreenMode debugFullScreenMode) | ||
|  |         { | ||
|  |             return TryGetFullscreenDebugMode(out debugFullScreenMode, out _); | ||
|  |         } | ||
|  | 
 | ||
|  |         internal bool TryGetFullscreenDebugMode(out DebugFullScreenMode debugFullScreenMode, out int textureHeightPercent) | ||
|  |         { | ||
|  |             debugFullScreenMode = RenderingSettings.fullScreenDebugMode; | ||
|  |             textureHeightPercent = RenderingSettings.fullScreenDebugModeOutputSizeScreenPercent; | ||
|  |             return debugFullScreenMode != DebugFullScreenMode.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal static void ConfigureColorDescriptorForDebugScreen(ref RenderTextureDescriptor descriptor, int cameraWidth, int cameraHeight) | ||
|  |         { | ||
|  |             descriptor.width = cameraWidth; | ||
|  |             descriptor.height = cameraHeight; | ||
|  |             descriptor.useMipMap = false; | ||
|  |             descriptor.autoGenerateMips = false; | ||
|  |             descriptor.useDynamicScale = true; | ||
|  |             descriptor.depthStencilFormat = GraphicsFormat.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal static void ConfigureDepthDescriptorForDebugScreen(ref RenderTextureDescriptor descriptor, GraphicsFormat depthStencilFormat, int cameraWidth, int cameraHeight) | ||
|  |         { | ||
|  |             descriptor.width = cameraWidth; | ||
|  |             descriptor.height = cameraHeight; | ||
|  |             descriptor.useMipMap = false; | ||
|  |             descriptor.autoGenerateMips = false; | ||
|  |             descriptor.useDynamicScale = true; | ||
|  |             descriptor.depthStencilFormat = depthStencilFormat; | ||
|  |             descriptor.graphicsFormat = GraphicsFormat.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | ||
|  |         internal void SetupShaderProperties(RasterCommandBuffer cmd, int passIndex = 0) | ||
|  |         { | ||
|  |             if (LightingSettings.lightingDebugMode == DebugLightingMode.ShadowCascades) | ||
|  |             { | ||
|  |                 // we disable cubemap reflections, too distracting (in TemplateLWRP for ex.) | ||
|  |                 cmd.EnableShaderKeyword("_DEBUG_ENVIRONMENTREFLECTIONS_OFF"); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 cmd.DisableShaderKeyword("_DEBUG_ENVIRONMENTREFLECTIONS_OFF"); | ||
|  |             } | ||
|  | 
 | ||
|  |             m_debugDisplayConstant.SetData(MaterialSettings.debugRenderingLayersColors, 0, 0, 32); | ||
|  | 
 | ||
|  |             cmd.SetGlobalConstantBuffer(m_debugDisplayConstant, "_DebugDisplayConstant", 0, m_debugDisplayConstant.count * m_debugDisplayConstant.stride); | ||
|  | 
 | ||
|  |             if (MaterialSettings.renderingLayersSelectedLight) | ||
|  |                 cmd.SetGlobalInt("_DebugRenderingLayerMask", (int)MaterialSettings.GetDebugLightLayersMask()); | ||
|  |             else | ||
|  |                 cmd.SetGlobalInt("_DebugRenderingLayerMask", (int)MaterialSettings.renderingLayerMask); | ||
|  | 
 | ||
|  |             switch (RenderingSettings.sceneOverrideMode) | ||
|  |             { | ||
|  |                 case DebugSceneOverrideMode.Overdraw: | ||
|  |                 { | ||
|  |                     // Target texture can contains only a value between 0 and 1 | ||
|  |                     // So we encode the number of overdraw in the range (0, max displayed overdaw count) | ||
|  |                     // The value will be clamped by the GPU driver | ||
|  |                     var value = 1 / (float)RenderingSettings.maxOverdrawCount; | ||
|  |                     cmd.SetGlobalColor(k_DebugColorPropertyId, new Color(value, value, value, 1)); | ||
|  |                     break; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 case DebugSceneOverrideMode.Wireframe: | ||
|  |                 { | ||
|  |                     cmd.SetGlobalColor(k_DebugColorPropertyId, Color.black); | ||
|  |                     break; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 case DebugSceneOverrideMode.SolidWireframe: | ||
|  |                 { | ||
|  |                     cmd.SetGlobalColor(k_DebugColorPropertyId, (passIndex == 0) ? Color.white : Color.black); | ||
|  |                     break; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 case DebugSceneOverrideMode.ShadedWireframe: | ||
|  |                 { | ||
|  |                     if (passIndex == 0) | ||
|  |                     { | ||
|  |                         cmd.SetKeyword(ShaderGlobalKeywords.DEBUG_DISPLAY, false); | ||
|  |                     } | ||
|  |                     else if (passIndex == 1) | ||
|  |                     { | ||
|  |                         cmd.SetGlobalColor(k_DebugColorPropertyId, Color.black); | ||
|  |                         cmd.SetKeyword(ShaderGlobalKeywords.DEBUG_DISPLAY, true); | ||
|  |                     } | ||
|  | 
 | ||
|  |                     break; | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             switch (MaterialSettings.materialValidationMode) | ||
|  |             { | ||
|  |                 case DebugMaterialValidationMode.Albedo: | ||
|  |                     cmd.SetGlobalFloat(k_DebugValidateAlbedoMinLuminanceId, MaterialSettings.albedoMinLuminance); | ||
|  |                     cmd.SetGlobalFloat(k_DebugValidateAlbedoMaxLuminanceId, MaterialSettings.albedoMaxLuminance); | ||
|  |                     cmd.SetGlobalFloat(k_DebugValidateAlbedoSaturationToleranceId, MaterialSettings.albedoSaturationTolerance); | ||
|  |                     cmd.SetGlobalFloat(k_DebugValidateAlbedoHueToleranceId, MaterialSettings.albedoHueTolerance); | ||
|  |                     cmd.SetGlobalColor(k_DebugValidateAlbedoCompareColorId, MaterialSettings.albedoCompareColor.linear); | ||
|  |                     break; | ||
|  | 
 | ||
|  |                 case DebugMaterialValidationMode.Metallic: | ||
|  |                     cmd.SetGlobalFloat(k_DebugValidateMetallicMinValueId, MaterialSettings.metallicMinValue); | ||
|  |                     cmd.SetGlobalFloat(k_DebugValidateMetallicMaxValueId, MaterialSettings.metallicMaxValue); | ||
|  |                     break; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void SetDebugRenderTarget(RTHandle renderTarget, Rect displayRect, bool supportsStereo, Vector4 dataRangeRemap) | ||
|  |         { | ||
|  |             m_HasDebugRenderTarget = true; | ||
|  |             m_DebugRenderTargetSupportsStereo = supportsStereo; | ||
|  |             m_DebugRenderTarget = renderTarget; | ||
|  |             m_DebugRenderTargetPixelRect = new Vector4(displayRect.x, displayRect.y, displayRect.width, displayRect.height); | ||
|  |             m_DebugRenderTargetRangeRemap = dataRangeRemap; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void ResetDebugRenderTarget() | ||
|  |         { | ||
|  |             m_HasDebugRenderTarget = false; | ||
|  |         } | ||
|  | 
 | ||
|  |         class DebugFinalValidationPassData | ||
|  |         { | ||
|  |             public bool isFinalPass; | ||
|  |             public bool resolveFinalTarget; | ||
|  |             public bool isActiveForCamera; | ||
|  |             public bool hasDebugRenderTarget; | ||
|  | 
 | ||
|  |             public TextureHandle debugRenderTargetHandle; | ||
|  |             public int debugTexturePropertyId; | ||
|  | 
 | ||
|  |             public Vector4 debugRenderTargetPixelRect; | ||
|  |             public int debugRenderTargetSupportsStereo; | ||
|  |             public Vector4 debugRenderTargetRangeRemap; | ||
|  | 
 | ||
|  |             public TextureHandle debugFontTextureHandle; | ||
|  | 
 | ||
|  |             // NOTE: The settings are references. | ||
|  |             // It's assumed they're the same for the whole frame. Build timeline != execution timeline! | ||
|  |             // Ideally these would be copied without any allocs. | ||
|  |             public DebugDisplaySettingsRendering renderingSettings; | ||
|  |         } | ||
|  | 
 | ||
|  |         DebugFinalValidationPassData InitDebugFinalValidationPassData(DebugFinalValidationPassData passData, UniversalCameraData cameraData, bool isFinalPass) | ||
|  |         { | ||
|  |             passData.isFinalPass = isFinalPass; | ||
|  |             passData.resolveFinalTarget = cameraData.resolveFinalTarget; | ||
|  |             passData.isActiveForCamera = IsActiveForCamera(cameraData.isPreviewCamera); | ||
|  |             passData.hasDebugRenderTarget = m_HasDebugRenderTarget; | ||
|  | 
 | ||
|  |             passData.debugRenderTargetHandle = TextureHandle.nullHandle; | ||
|  |             passData.debugTexturePropertyId = m_DebugRenderTargetSupportsStereo ? k_DebugTexturePropertyId : k_DebugTextureNoStereoPropertyId; | ||
|  | 
 | ||
|  |             passData.debugRenderTargetPixelRect = m_DebugRenderTargetPixelRect; | ||
|  |             passData.debugRenderTargetSupportsStereo = m_DebugRenderTargetSupportsStereo ? 1 : 0; | ||
|  |             passData.debugRenderTargetRangeRemap = m_DebugRenderTargetRangeRemap; | ||
|  | 
 | ||
|  |             passData.debugFontTextureHandle = TextureHandle.nullHandle; | ||
|  | 
 | ||
|  |             passData.renderingSettings = RenderingSettings; | ||
|  | 
 | ||
|  |             return passData; | ||
|  |         } | ||
|  | 
 | ||
|  |         static void UpdateShaderGlobalPropertiesForFinalValidationPass(RasterCommandBuffer cmd, DebugFinalValidationPassData data) | ||
|  |         { | ||
|  |             // Ensure final validation & fullscreen debug modes are only done once in the very final pass, for the last camera on the stack. | ||
|  |             bool isFinal = data.isFinalPass && data.resolveFinalTarget; | ||
|  |             if (!isFinal) | ||
|  |             { | ||
|  |                 cmd.SetKeyword(ShaderGlobalKeywords.DEBUG_DISPLAY, false); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             if (data.isActiveForCamera) | ||
|  |             { | ||
|  |                 cmd.SetKeyword(ShaderGlobalKeywords.DEBUG_DISPLAY, true); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 cmd.SetKeyword(ShaderGlobalKeywords.DEBUG_DISPLAY, false); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (data.hasDebugRenderTarget) | ||
|  |             { | ||
|  |                 if(data.debugRenderTargetHandle.IsValid()) | ||
|  |                     cmd.SetGlobalTexture(data.debugTexturePropertyId,  data.debugRenderTargetHandle); | ||
|  | 
 | ||
|  |                 cmd.SetGlobalVector(k_DebugTextureDisplayRect, data.debugRenderTargetPixelRect); | ||
|  |                 cmd.SetGlobalInteger(k_DebugRenderTargetSupportsStereo, data.debugRenderTargetSupportsStereo); | ||
|  |                 cmd.SetGlobalVector(k_DebugRenderTargetRangeRemap, data.debugRenderTargetRangeRemap); | ||
|  |             } | ||
|  | 
 | ||
|  |             var renderingSettings = data.renderingSettings; | ||
|  |             if (renderingSettings.validationMode == DebugValidationMode.HighlightOutsideOfRange) | ||
|  |             { | ||
|  |                 cmd.SetGlobalInteger(k_ValidationChannelsId, (int)renderingSettings.validationChannels); | ||
|  |                 cmd.SetGlobalFloat(k_RangeMinimumId, renderingSettings.validationRangeMin); | ||
|  |                 cmd.SetGlobalFloat(k_RangeMaximumId, renderingSettings.validationRangeMax); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (renderingSettings.mipInfoMode != DebugMipInfoMode.None) | ||
|  |             { | ||
|  |                 // some (not all) of these need text rendering | ||
|  |                 cmd.SetGlobalTexture(k_DebugFontId, data.debugFontTextureHandle); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | ||
|  |         internal void UpdateShaderGlobalPropertiesForFinalValidationPass(CommandBuffer cmd, UniversalCameraData cameraData, bool isFinalPass) | ||
|  |         { | ||
|  |             UpdateShaderGlobalPropertiesForFinalValidationPass(CommandBufferHelpers.GetRasterCommandBuffer(cmd), InitDebugFinalValidationPassData(s_DebugFinalValidationPassData, cameraData, isFinalPass)); | ||
|  |             cmd.SetGlobalTexture(s_DebugFinalValidationPassData.debugTexturePropertyId,  m_DebugRenderTarget); | ||
|  |             if (RenderingSettings.mipInfoMode != DebugMipInfoMode.None) | ||
|  |             { | ||
|  |                 // some (not all) of these need text rendering | ||
|  |                 cmd.SetGlobalTexture(k_DebugFontId, m_RuntimeTextures.debugFontTexture); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | ||
|  |         internal void UpdateShaderGlobalPropertiesForFinalValidationPass(RenderGraph renderGraph, UniversalCameraData cameraData, bool isFinalPass) | ||
|  |         { | ||
|  |             using (var builder = renderGraph.AddRasterRenderPass<DebugFinalValidationPassData>(nameof(UpdateShaderGlobalPropertiesForFinalValidationPass), out var passData, s_DebugFinalValidationSampler)) | ||
|  |             { | ||
|  |                 InitDebugFinalValidationPassData(passData, cameraData, isFinalPass); | ||
|  | 
 | ||
|  |                 if (m_DebugRenderTarget != null) | ||
|  |                     passData.debugRenderTargetHandle = renderGraph.ImportTexture(m_DebugRenderTarget); | ||
|  | 
 | ||
|  |                 if (m_DebugFontTexture != null) | ||
|  |                     passData.debugFontTextureHandle = renderGraph.ImportTexture(m_DebugFontTexture); | ||
|  | 
 | ||
|  |                 builder.AllowGlobalStateModification(true); | ||
|  | 
 | ||
|  |                 if (passData.debugRenderTargetHandle.IsValid()) | ||
|  |                 { | ||
|  |                     builder.UseTexture(passData.debugRenderTargetHandle); | ||
|  |                     builder.SetGlobalTextureAfterPass(passData.debugRenderTargetHandle, passData.debugTexturePropertyId); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (passData.debugFontTextureHandle.IsValid()) | ||
|  |                 { | ||
|  |                     builder.UseTexture(passData.debugFontTextureHandle); | ||
|  |                     builder.SetGlobalTextureAfterPass(passData.debugFontTextureHandle, k_DebugFontId); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 builder.SetRenderFunc(static (DebugFinalValidationPassData data, RasterGraphContext context) => | ||
|  |                 { | ||
|  |                     UpdateShaderGlobalPropertiesForFinalValidationPass(context.cmd, data); | ||
|  |                 }); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         class DebugSetupPassData | ||
|  |         { | ||
|  |             public bool isActiveForCamera; | ||
|  | 
 | ||
|  |             // NOTE: The settings are references. | ||
|  |             // It's assumed they're the same for the whole frame. Build timeline != execution timeline! | ||
|  |             // Ideally these would be copied without any allocs. | ||
|  |             public DebugDisplaySettingsMaterial  materialSettings; | ||
|  |             public DebugDisplaySettingsRendering renderingSettings; | ||
|  |             public DebugDisplaySettingsLighting  lightingSettings; | ||
|  |         } | ||
|  | 
 | ||
|  |         DebugSetupPassData InitDebugSetupPassData(DebugSetupPassData passData, bool isPreviewCamera) | ||
|  |         { | ||
|  |             passData.isActiveForCamera = IsActiveForCamera(isPreviewCamera); | ||
|  |             passData.materialSettings  = MaterialSettings; | ||
|  |             passData.renderingSettings = RenderingSettings; | ||
|  |             passData.lightingSettings  = LightingSettings; | ||
|  |             return passData; | ||
|  |         } | ||
|  | 
 | ||
|  |         [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | ||
|  |         static void Setup(RasterCommandBuffer cmd, DebugSetupPassData passData) | ||
|  |         { | ||
|  |             if (passData.isActiveForCamera) | ||
|  |             { | ||
|  |                 cmd.SetKeyword(ShaderGlobalKeywords.DEBUG_DISPLAY, true); | ||
|  | 
 | ||
|  |                 // Material settings... | ||
|  |                 cmd.SetGlobalFloat(k_DebugMaterialModeId, (int)passData.materialSettings.materialDebugMode); | ||
|  |                 cmd.SetGlobalFloat(k_DebugVertexAttributeModeId, (int)passData.materialSettings.vertexAttributeDebugMode); | ||
|  | 
 | ||
|  |                 cmd.SetGlobalInteger(k_DebugMaterialValidationModeId, (int)passData.materialSettings.materialValidationMode); | ||
|  | 
 | ||
|  |                 // Rendering settings... | ||
|  |                 cmd.SetGlobalInteger(k_DebugMipInfoModeId, (int)passData.renderingSettings.mipInfoMode); | ||
|  |                 cmd.SetGlobalInteger(k_DebugMipMapStatusModeId, (int)passData.renderingSettings.mipDebugStatusMode); | ||
|  |                 cmd.SetGlobalInteger(k_DebugMipMapShowStatusCodeId, passData.renderingSettings.mipDebugStatusShowCode ? 1 : 0); | ||
|  |                 cmd.SetGlobalFloat(k_DebugMipMapOpacityId, passData.renderingSettings.mipDebugOpacity); | ||
|  |                 cmd.SetGlobalFloat(k_DebugMipMapRecentlyUpdatedCooldownId, passData.renderingSettings.mipDebugRecentUpdateCooldown); | ||
|  |                 cmd.SetGlobalFloat(k_DebugMipMapTerrainTextureModeId, (int)passData.renderingSettings.mipDebugTerrainTexture); | ||
|  |                 cmd.SetGlobalInteger(k_DebugSceneOverrideModeId, (int)passData.renderingSettings.sceneOverrideMode); | ||
|  |                 cmd.SetGlobalInteger(k_DebugFullScreenModeId, (int)passData.renderingSettings.fullScreenDebugMode); | ||
|  |                 cmd.SetGlobalInteger(k_DebugMaxPixelCost, (int)passData.renderingSettings.maxOverdrawCount); | ||
|  |                 cmd.SetGlobalInteger(k_DebugValidationModeId, (int)passData.renderingSettings.validationMode); | ||
|  |                 cmd.SetGlobalColor(k_DebugValidateBelowMinThresholdColorPropertyId, Color.red); | ||
|  |                 cmd.SetGlobalColor(k_DebugValidateAboveMaxThresholdColorPropertyId, Color.blue); | ||
|  | 
 | ||
|  |                 // Lighting settings... | ||
|  |                 cmd.SetGlobalFloat(k_DebugLightingModeId, (int)passData.lightingSettings.lightingDebugMode); | ||
|  |                 cmd.SetGlobalInteger(k_DebugLightingFeatureFlagsId, (int)passData.lightingSettings.lightingFeatureFlags); | ||
|  | 
 | ||
|  |                 // Set-up any other persistent properties... | ||
|  |                 cmd.SetGlobalColor(k_DebugColorInvalidModePropertyId, Color.red); | ||
|  | #if UNITY_EDITOR | ||
|  |                 cmd.SetGlobalFloat(k_DebugCurrentRealTimeId, (float)EditorApplication.timeSinceStartup); | ||
|  | #else | ||
|  |                 cmd.SetGlobalFloat(k_DebugCurrentRealTimeId, Time.realtimeSinceStartup); | ||
|  | #endif | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 cmd.SetKeyword(ShaderGlobalKeywords.DEBUG_DISPLAY, false); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | ||
|  |         internal void Setup(CommandBuffer cmd, bool isPreviewCamera) | ||
|  |         { | ||
|  |             Setup(CommandBufferHelpers.GetRasterCommandBuffer(cmd), InitDebugSetupPassData(s_DebugSetupPassData, isPreviewCamera)); | ||
|  |         } | ||
|  | 
 | ||
|  |         [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | ||
|  |         internal void Setup(RenderGraph renderGraph, bool isPreviewCamera) | ||
|  |         { | ||
|  |             using (var builder = renderGraph.AddRasterRenderPass<DebugSetupPassData>(s_DebugSetupSampler.name, out var passData, s_DebugSetupSampler)) | ||
|  |             { | ||
|  |                 InitDebugSetupPassData(passData, isPreviewCamera); | ||
|  |                 builder.AllowGlobalStateModification(true); | ||
|  |                 builder.SetRenderFunc(static (DebugSetupPassData data, RasterGraphContext context) => | ||
|  |                 { | ||
|  |                     Setup(context.cmd, data); | ||
|  |                 }); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | ||
|  |         internal void Render(RenderGraph renderGraph, UniversalCameraData cameraData, TextureHandle srcColor, TextureHandle overlayTexture, TextureHandle dstColor) | ||
|  |         { | ||
|  |             if (IsActiveForCamera(cameraData.isPreviewCamera) && HDRDebugViewIsActive(cameraData.resolveFinalTarget)) | ||
|  |             { | ||
|  |                 m_HDRDebugViewPass.RenderHDRDebug(renderGraph, cameraData, srcColor, overlayTexture, dstColor, LightingSettings.hdrDebugMode); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         #region DebugRendererLists | ||
|  | 
 | ||
|  |         internal DebugRendererLists CreateRendererListsWithDebugRenderState( | ||
|  |              ScriptableRenderContext context, | ||
|  |              ref CullingResults cullResults, | ||
|  |              ref DrawingSettings drawingSettings, | ||
|  |              ref FilteringSettings filteringSettings, | ||
|  |              ref RenderStateBlock renderStateBlock) | ||
|  |         { | ||
|  |             DebugRendererLists debug = new DebugRendererLists(this, filteringSettings); | ||
|  |             debug.CreateRendererListsWithDebugRenderState(context, ref cullResults, ref drawingSettings, ref filteringSettings, ref renderStateBlock); | ||
|  |             return debug; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal DebugRendererLists CreateRendererListsWithDebugRenderState( | ||
|  |             RenderGraph renderGraph, | ||
|  |             ref CullingResults cullResults, | ||
|  |             ref DrawingSettings drawingSettings, | ||
|  |             ref FilteringSettings filteringSettings, | ||
|  |             ref RenderStateBlock renderStateBlock) | ||
|  |         { | ||
|  |             DebugRendererLists debug = new DebugRendererLists(this, filteringSettings); | ||
|  |             debug.CreateRendererListsWithDebugRenderState(renderGraph, ref cullResults, ref drawingSettings, ref filteringSettings, ref renderStateBlock); | ||
|  |             return debug; | ||
|  |         } | ||
|  |         #endregion | ||
|  |     } | ||
|  | 
 | ||
|  |     internal class DebugRendererLists | ||
|  |     { | ||
|  |         private readonly DebugHandler m_DebugHandler; | ||
|  |         readonly FilteringSettings m_FilteringSettings; | ||
|  |         List<DebugRenderSetup> m_DebugRenderSetups = new List<DebugRenderSetup>(2); | ||
|  |         List<RendererList> m_ActiveDebugRendererList = new List<RendererList>(2); | ||
|  |         List<RendererListHandle> m_ActiveDebugRendererListHdl = new List<RendererListHandle>(2); | ||
|  | 
 | ||
|  |         public DebugRendererLists(DebugHandler debugHandler, | ||
|  |             FilteringSettings filteringSettings) | ||
|  |         { | ||
|  |             m_DebugHandler = debugHandler; | ||
|  |             m_FilteringSettings = filteringSettings; | ||
|  |         } | ||
|  | 
 | ||
|  |         private void CreateDebugRenderSetups(FilteringSettings filteringSettings) | ||
|  |         { | ||
|  |             var sceneOverrideMode = m_DebugHandler.DebugDisplaySettings.renderingSettings.sceneOverrideMode; | ||
|  |             var numIterations = ((sceneOverrideMode == DebugSceneOverrideMode.SolidWireframe) || (sceneOverrideMode == DebugSceneOverrideMode.ShadedWireframe)) ? 2 : 1; | ||
|  |             for (var i = 0; i < numIterations; i++) | ||
|  |                 m_DebugRenderSetups.Add(new DebugRenderSetup(m_DebugHandler, i, filteringSettings)); | ||
|  |         } | ||
|  | 
 | ||
|  |         void DisposeDebugRenderLists() | ||
|  |         { | ||
|  |             foreach (var debugRenderSetup in m_DebugRenderSetups) | ||
|  |             { | ||
|  |                 debugRenderSetup.Dispose(); | ||
|  |             } | ||
|  |             m_DebugRenderSetups.Clear(); | ||
|  |             m_ActiveDebugRendererList.Clear(); | ||
|  |             m_ActiveDebugRendererListHdl.Clear(); | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void CreateRendererListsWithDebugRenderState( | ||
|  |              ScriptableRenderContext context, | ||
|  |              ref CullingResults cullResults, | ||
|  |              ref DrawingSettings drawingSettings, | ||
|  |              ref FilteringSettings filteringSettings, | ||
|  |              ref RenderStateBlock renderStateBlock) | ||
|  |         { | ||
|  |             CreateDebugRenderSetups(filteringSettings); | ||
|  |             foreach (DebugRenderSetup debugRenderSetup in m_DebugRenderSetups) | ||
|  |             { | ||
|  |                 DrawingSettings debugDrawingSettings = debugRenderSetup.CreateDrawingSettings(drawingSettings); | ||
|  |                 RenderStateBlock debugRenderStateBlock = debugRenderSetup.GetRenderStateBlock(renderStateBlock); | ||
|  |                 RendererList rendererList = new RendererList(); | ||
|  |                 RenderingUtils.CreateRendererListWithRenderStateBlock(context, ref cullResults, debugDrawingSettings, filteringSettings, debugRenderStateBlock, ref rendererList); | ||
|  |                 m_ActiveDebugRendererList.Add((rendererList)); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void CreateRendererListsWithDebugRenderState( | ||
|  |             RenderGraph renderGraph, | ||
|  |             ref CullingResults cullResults, | ||
|  |             ref DrawingSettings drawingSettings, | ||
|  |             ref FilteringSettings filteringSettings, | ||
|  |             ref RenderStateBlock renderStateBlock) | ||
|  |         { | ||
|  |             CreateDebugRenderSetups(filteringSettings); | ||
|  |             foreach (DebugRenderSetup debugRenderSetup in m_DebugRenderSetups) | ||
|  |             { | ||
|  |                 DrawingSettings debugDrawingSettings = debugRenderSetup.CreateDrawingSettings(drawingSettings); | ||
|  |                 RenderStateBlock debugRenderStateBlock = debugRenderSetup.GetRenderStateBlock(renderStateBlock); | ||
|  |                 RendererListHandle rendererListHdl = new RendererListHandle(); | ||
|  |                 RenderingUtils.CreateRendererListWithRenderStateBlock(renderGraph, ref cullResults, debugDrawingSettings, filteringSettings, debugRenderStateBlock, ref rendererListHdl); | ||
|  |                 m_ActiveDebugRendererListHdl.Add((rendererListHdl)); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void PrepareRendererListForRasterPass(IRasterRenderGraphBuilder builder) | ||
|  |         { | ||
|  |             foreach (RendererListHandle rendererListHdl in m_ActiveDebugRendererListHdl) | ||
|  |             { | ||
|  |                 builder.UseRendererList(rendererListHdl); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void DrawWithRendererList(RasterCommandBuffer cmd) | ||
|  |         { | ||
|  |             foreach (DebugRenderSetup debugRenderSetup in m_DebugRenderSetups) | ||
|  |             { | ||
|  |                 debugRenderSetup.Begin(cmd); | ||
|  |                 RendererList rendererList = new RendererList(); | ||
|  |                 if (m_ActiveDebugRendererList.Count > 0) | ||
|  |                 { | ||
|  |                     rendererList = m_ActiveDebugRendererList[debugRenderSetup.GetIndex()]; | ||
|  |                 } | ||
|  |                 else if(m_ActiveDebugRendererListHdl.Count > 0) | ||
|  |                 { | ||
|  |                     rendererList = m_ActiveDebugRendererListHdl[debugRenderSetup.GetIndex()]; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 debugRenderSetup.DrawWithRendererList(cmd, ref rendererList); | ||
|  |                 debugRenderSetup.End(cmd); | ||
|  |             } | ||
|  | 
 | ||
|  |             DisposeDebugRenderLists(); | ||
|  |         } | ||
|  |     } | ||
|  | } |