diff --git a/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs b/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs index 17f40a20d6e..ca626faf352 100644 --- a/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs +++ b/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs @@ -19,7 +19,7 @@ public class ConstantBuffer /// Shader porperty id to bind the constant buffer to. public static void PushGlobal(CommandBuffer cmd, in CBType data, int shaderId) where CBType : struct { - var cb = TypedConstantBuffer.instance; + var cb = ConstantBufferSingleton.instance; cb.UpdateData(cmd, data); cb.SetGlobal(cmd, shaderId); @@ -35,7 +35,7 @@ public static void PushGlobal(CommandBuffer cmd, in CBType data, int sha /// Shader porperty id to bind the constant buffer to. public static void Push(CommandBuffer cmd, in CBType data, ComputeShader cs, int shaderId) where CBType : struct { - var cb = TypedConstantBuffer.instance; + var cb = ConstantBufferSingleton.instance; cb.UpdateData(cmd, data); cb.Set(cmd, cs, shaderId); @@ -51,7 +51,7 @@ public static void Push(CommandBuffer cmd, in CBType data, ComputeShader /// Shader porperty id to bind the constant buffer to. public static void Push(CommandBuffer cmd, in CBType data, Material mat, int shaderId) where CBType : struct { - var cb = TypedConstantBuffer.instance; + var cb = ConstantBufferSingleton.instance; cb.UpdateData(cmd, data); cb.Set(mat, shaderId); @@ -65,7 +65,7 @@ public static void Push(CommandBuffer cmd, in CBType data, Material mat, /// Input data of the constant buffer. public static void UpdateData(CommandBuffer cmd, in CBType data) where CBType : struct { - var cb = TypedConstantBuffer.instance; + var cb = ConstantBufferSingleton.instance; cb.UpdateData(cmd, data); } @@ -78,7 +78,7 @@ public static void UpdateData(CommandBuffer cmd, in CBType data) where C /// Shader porperty id to bind the constant buffer to. public static void SetGlobal(CommandBuffer cmd, int shaderId) where CBType : struct { - var cb = TypedConstantBuffer.instance; + var cb = ConstantBufferSingleton.instance; cb.SetGlobal(cmd, shaderId); } @@ -92,7 +92,7 @@ public static void SetGlobal(CommandBuffer cmd, int shaderId) where CBTy /// Shader porperty id to bind the constant buffer to. public static void Set(CommandBuffer cmd, ComputeShader cs, int shaderId) where CBType : struct { - var cb = TypedConstantBuffer.instance; + var cb = ConstantBufferSingleton.instance; cb.Set(cmd, cs, shaderId); } @@ -105,13 +105,13 @@ public static void Set(CommandBuffer cmd, ComputeShader cs, int shaderId /// Shader porperty id to bind the constant buffer to. public static void Set(Material mat, int shaderId) where CBType : struct { - var cb = TypedConstantBuffer.instance; + var cb = ConstantBufferSingleton.instance; cb.Set(mat, shaderId); } /// - /// Release all currently allocated constant buffers. + /// Release all currently allocated singleton constant buffers. /// This needs to be called before shutting down the application. /// public static void ReleaseAll() @@ -122,86 +122,148 @@ public static void ReleaseAll() m_RegisteredConstantBuffers.Clear(); } - internal abstract class ConstantBufferBase - { - public abstract void Release(); - } - internal static void Register(ConstantBufferBase cb) { m_RegisteredConstantBuffers.Add(cb); } + } - class TypedConstantBuffer : ConstantBufferBase where CBType : struct - { - // Used to track all global bindings used by this CB type. - HashSet m_GlobalBindings = new HashSet(); - // Array is required by the ComputeBuffer SetData API - CBType[] m_Data = new CBType[1]; + /// + /// The base class of Constant Buffer. + /// + public abstract class ConstantBufferBase + { + /// + /// Release the constant buffer. + /// + public abstract void Release(); + } - static TypedConstantBuffer s_Instance = null; - internal static TypedConstantBuffer instance - { - get - { - if (s_Instance == null) - s_Instance = new TypedConstantBuffer(); - return s_Instance; - } - set - { - s_Instance = value; - } - } - ComputeBuffer m_GPUConstantBuffer = null; - TypedConstantBuffer() - { - m_GPUConstantBuffer = new ComputeBuffer(1, UnsafeUtility.SizeOf(), ComputeBufferType.Constant); - ConstantBuffer.Register(this); - } + /// + /// An instance of a constant buffer. + /// + /// The type of structure representing the constant buffer data. + public class ConstantBuffer : ConstantBufferBase where CBType : struct + { + // Used to track all global bindings used by this CB type. + HashSet m_GlobalBindings = new HashSet(); + // Array is required by the ComputeBuffer SetData API + CBType[] m_Data = new CBType[1]; - public void UpdateData(CommandBuffer cmd, in CBType data) - { - m_Data[0] = data; + + ComputeBuffer m_GPUConstantBuffer = null; + + /// + /// Constant Buffer constructor. + /// + public ConstantBuffer() + { + m_GPUConstantBuffer = new ComputeBuffer(1, UnsafeUtility.SizeOf(), ComputeBufferType.Constant); + } + + /// + /// Update the GPU data of the constant buffer. + /// + /// Command Buffer used to execute the graphic commands. + /// Input data of the constant buffer. + public void UpdateData(CommandBuffer cmd, in CBType data) + { + m_Data[0] = data; #if UNITY_2021_1_OR_NEWER - cmd.SetBufferData(m_GPUConstantBuffer, m_Data); + cmd.SetBufferData(m_GPUConstantBuffer, m_Data); #else - cmd.SetComputeBufferData(m_GPUConstantBuffer, m_Data); + cmd.SetComputeBufferData(m_GPUConstantBuffer, m_Data); #endif - } + } - public void SetGlobal(CommandBuffer cmd, int shaderId) - { - m_GlobalBindings.Add(shaderId); - cmd.SetGlobalConstantBuffer(m_GPUConstantBuffer, shaderId, 0, m_GPUConstantBuffer.stride); - } + /// + /// Bind the constant buffer globally. + /// + /// Command Buffer used to execute the graphic commands. + /// Shader porperty id to bind the constant buffer to. + public void SetGlobal(CommandBuffer cmd, int shaderId) + { + m_GlobalBindings.Add(shaderId); + cmd.SetGlobalConstantBuffer(m_GPUConstantBuffer, shaderId, 0, m_GPUConstantBuffer.stride); + } - public void Set(CommandBuffer cmd, ComputeShader cs, int shaderId) - { - cmd.SetComputeConstantBufferParam(cs, shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride); - } + /// + /// Bind the constant buffer to a compute shader. + /// + /// Command Buffer used to execute the graphic commands. + /// Compute shader to which the constant buffer should be bound. + /// Shader porperty id to bind the constant buffer to. + public void Set(CommandBuffer cmd, ComputeShader cs, int shaderId) + { + cmd.SetComputeConstantBufferParam(cs, shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride); + } + + /// + /// Bind the constant buffer to a material. + /// + /// Material to which the constant buffer should be bound. + /// Shader porperty id to bind the constant buffer to. + public void Set(Material mat, int shaderId) + { + // This isn't done via command buffer because as long as the buffer itself is not destroyed, + // the binding stays valid. Only the commit of data needs to go through the command buffer. + // We do it here anyway for now to simplify user API. + mat.SetConstantBuffer(shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride); + } + + /// + /// Update the GPU data of the constant buffer and bind it globally. + /// + /// Command Buffer used to execute the graphic commands. + /// Input data of the constant buffer. + /// Shader porperty id to bind the constant buffer to. + public void PushGlobal(CommandBuffer cmd, in CBType data, int shaderId) + { + UpdateData(cmd, data); + SetGlobal(cmd, shaderId); + } + + /// + /// Release the constant buffers. + /// + public override void Release() + { + // Depending on the device, globally bound buffers can leave stale "valid" shader ids pointing to a destroyed buffer. + // In DX11 it does not cause issues but on Vulkan this will result in skipped drawcalls (even if the buffer is not actually accessed in the shader). + // To avoid this kind of issues, it's good practice to "unbind" all globally bound buffers upon destruction. + foreach (int shaderId in m_GlobalBindings) + Shader.SetGlobalConstantBuffer(shaderId, (ComputeBuffer)null, 0, 0); + m_GlobalBindings.Clear(); - public void Set(Material mat, int shaderId) + CoreUtils.SafeRelease(m_GPUConstantBuffer); + } + } + + class ConstantBufferSingleton : ConstantBuffer where CBType : struct + { + static ConstantBufferSingleton s_Instance = null; + internal static ConstantBufferSingleton instance + { + get { - // This isn't done via command buffer because as long as the buffer itself is not destroyed, - // the binding stays valid. Only the commit of data needs to go through the command buffer. - // We do it here anyway for now to simplify user API. - mat.SetConstantBuffer(shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride); + if (s_Instance == null) + { + s_Instance = new ConstantBufferSingleton(); + ConstantBuffer.Register(s_Instance); + } + return s_Instance; } - - public override void Release() + set { - // Depending on the device, globally bound buffers can leave stale "valid" shader ids pointing to a destroyed buffer. - // In DX11 it does not cause issues but on Vulkan this will result in skipped drawcalls (even if the buffer is not actually accessed in the shader). - // To avoid this kind of issues, it's good practice to "unbind" all globally bound buffers upon destruction. - foreach (int shaderId in m_GlobalBindings) - Shader.SetGlobalConstantBuffer(shaderId, (ComputeBuffer)null, 0, 0); - m_GlobalBindings.Clear(); - - CoreUtils.SafeRelease(m_GPUConstantBuffer); - s_Instance = null; + s_Instance = value; } } + + public override void Release() + { + base.Release(); + s_Instance = null; + } } } diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 2a722d28d33..fc2504818eb 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -168,6 +168,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed usage of Panini Projection with floating point HDRP and Post Processing color buffers. - Fixed a NaN generating in Area light code. - Fixed CustomPassUtils scaling issues when used with RTHandles allocated from a RenderTexture. +- Fixed issue with constant buffer being stomped on when async tasks run concurrently to shadows. ### Changed - Removed the material pass probe volumes evaluation mode. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowAtlas.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowAtlas.cs index 7f0f139e7f3..16a7d15075f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowAtlas.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowAtlas.cs @@ -77,9 +77,9 @@ public HDCachedShadowAtlas(ShadowMapType type) m_ShadowType = type; } - public override void InitAtlas(RenderPipelineResources renderPipelineResources, RenderGraph renderGraph, bool useSharedTexture, int width, int height, int atlasShaderID, Material clearMaterial, int maxShadowRequests, HDShadowInitParameters initParams, BlurAlgorithm blurAlgorithm = BlurAlgorithm.None, FilterMode filterMode = FilterMode.Bilinear, DepthBits depthBufferBits = DepthBits.Depth16, RenderTextureFormat format = RenderTextureFormat.Shadowmap, string name = "") + public override void InitAtlas(HDShadowAtlasInitParameters atlasInitParams) { - base.InitAtlas(renderPipelineResources, renderGraph, useSharedTexture, width, height, atlasShaderID, clearMaterial, maxShadowRequests, initParams, blurAlgorithm, filterMode, depthBufferBits, format, name); + base.InitAtlas(atlasInitParams); m_IsACacheForShadows = true; m_AtlasResolutionInSlots = HDUtils.DivRoundUp(width, m_MinSlotSize); @@ -91,7 +91,7 @@ public override void InitAtlas(RenderPipelineResources renderPipelineResources, // Note: If changing the characteristics of the atlas via HDRP asset, the lights OnEnable will not be called again so we are missing them, however we can explicitly // put them back up for placement. If this is the first Init of the atlas, the lines below do nothing. - DefragmentAtlasAndReRender(initParams); + DefragmentAtlasAndReRender(atlasInitParams.initParams); m_CanTryPlacement = true; m_NeedOptimalPacking = true; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowManager.cs index 056a964877d..56ff0ffaea9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDCachedShadowManager.cs @@ -274,18 +274,16 @@ private HDCachedShadowManager() areaShadowAtlas = new HDCachedShadowAtlas(ShadowMapType.AreaLightAtlas); } - internal void InitPunctualShadowAtlas(RenderPipelineResources renderPipelineResources, RenderGraph renderGraph, bool useSharedTexture, int width, int height, int atlasShaderID, Material clearMaterial, int maxShadowRequests, HDShadowInitParameters initParams, - HDShadowAtlas.BlurAlgorithm blurAlgorithm = HDShadowAtlas.BlurAlgorithm.None, FilterMode filterMode = FilterMode.Bilinear, DepthBits depthBufferBits = DepthBits.Depth16, RenderTextureFormat format = RenderTextureFormat.Shadowmap, string name = "") + internal void InitPunctualShadowAtlas(HDShadowAtlas.HDShadowAtlasInitParameters atlasInitParams) { - m_InitParams = initParams; - punctualShadowAtlas.InitAtlas(renderPipelineResources, renderGraph, useSharedTexture, width, height, atlasShaderID, clearMaterial, maxShadowRequests, initParams, blurAlgorithm, filterMode, depthBufferBits, format, name); + m_InitParams = atlasInitParams.initParams; + punctualShadowAtlas.InitAtlas(atlasInitParams); } - internal void InitAreaLightShadowAtlas(RenderPipelineResources renderPipelineResources, RenderGraph renderGraph, bool useSharedTexture, int width, int height, int atlasShaderID, Material clearMaterial, int maxShadowRequests, HDShadowInitParameters initParams, - HDShadowAtlas.BlurAlgorithm blurAlgorithm = HDShadowAtlas.BlurAlgorithm.None, FilterMode filterMode = FilterMode.Bilinear, DepthBits depthBufferBits = DepthBits.Depth16, RenderTextureFormat format = RenderTextureFormat.Shadowmap, string name = "") + internal void InitAreaLightShadowAtlas(HDShadowAtlas.HDShadowAtlasInitParameters atlasInitParams) { - m_InitParams = initParams; - areaShadowAtlas.InitAtlas(renderPipelineResources, renderGraph, useSharedTexture, width, height, atlasShaderID, clearMaterial, maxShadowRequests, initParams, blurAlgorithm, filterMode, depthBufferBits, format, name); + m_InitParams = atlasInitParams.initParams; + areaShadowAtlas.InitAtlas(atlasInitParams); } internal void RegisterLight(HDAdditionalLightData lightData) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDDynamicShadowAtlas.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDDynamicShadowAtlas.cs index 9da9f7e01f4..ae5b5037b81 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDDynamicShadowAtlas.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDDynamicShadowAtlas.cs @@ -12,10 +12,10 @@ partial class HDDynamicShadowAtlas : HDShadowAtlas float m_RcpScaleFactor = 1; HDShadowResolutionRequest[] m_SortedRequestsCache; - public HDDynamicShadowAtlas(RenderPipelineResources renderPipelineResources, RenderGraph renderGraph, bool useSharedTexture, int width, int height, int atlasShaderID, Material clearMaterial, int maxShadowRequests, HDShadowInitParameters initParams, BlurAlgorithm blurAlgorithm = BlurAlgorithm.None, FilterMode filterMode = FilterMode.Bilinear, DepthBits depthBufferBits = DepthBits.Depth16, RenderTextureFormat format = RenderTextureFormat.Shadowmap, string name = "") - : base(renderPipelineResources, renderGraph, useSharedTexture, width, height, atlasShaderID, clearMaterial, maxShadowRequests, initParams, blurAlgorithm, filterMode, depthBufferBits, format, name) + public HDDynamicShadowAtlas(HDShadowAtlasInitParameters atlaInitParams) + : base(atlaInitParams) { - m_SortedRequestsCache = new HDShadowResolutionRequest[Mathf.CeilToInt(maxShadowRequests)]; + m_SortedRequestsCache = new HDShadowResolutionRequest[Mathf.CeilToInt(atlaInitParams.maxShadowRequests)]; } internal void ReserveResolution(HDShadowResolutionRequest shadowRequest) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAtlas.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAtlas.cs index 32fb14d25be..2164f844d1c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAtlas.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAtlas.cs @@ -7,6 +7,47 @@ namespace UnityEngine.Rendering.HighDefinition { abstract partial class HDShadowAtlas { + internal struct HDShadowAtlasInitParameters + { + internal RenderPipelineResources renderPipelineResources; + internal RenderGraph renderGraph; + internal bool useSharedTexture; + internal int width; + internal int height; + internal int atlasShaderID; + internal int maxShadowRequests; + internal string name; + + internal Material clearMaterial; + internal HDShadowInitParameters initParams; + internal BlurAlgorithm blurAlgorithm; + internal FilterMode filterMode; + internal DepthBits depthBufferBits; + internal RenderTextureFormat format; + internal ConstantBuffer cb; + + internal HDShadowAtlasInitParameters(RenderPipelineResources renderPipelineResources, RenderGraph renderGraph, bool useSharedTexture, int width, int height, int atlasShaderID, + Material clearMaterial, int maxShadowRequests, HDShadowInitParameters initParams, ConstantBuffer cb) + { + this.renderPipelineResources = renderPipelineResources; + this.renderGraph = renderGraph; + this.useSharedTexture = useSharedTexture; + this.width = width; + this.height = height; + this.atlasShaderID = atlasShaderID; + this.clearMaterial = clearMaterial; + this.maxShadowRequests = maxShadowRequests; + this.initParams = initParams; + this.blurAlgorithm = BlurAlgorithm.None; + this.filterMode = FilterMode.Bilinear; + this.depthBufferBits = DepthBits.Depth16; + this.format = RenderTextureFormat.Shadowmap; + this.name = ""; + + this.cb = cb; + } + } + public enum BlurAlgorithm { None, @@ -35,6 +76,9 @@ public enum BlurAlgorithm // Moment shadow data BlurAlgorithm m_BlurAlgorithm; + // This is only a reference that is hold by the atlas, but its lifetime is responsibility of the shadow manager. + ConstantBuffer m_GlobalConstantBuffer; + // This must be true for atlas that contain cached data (effectively this // drives what to do with mixed cached shadow map -> if true we filter with only static // if false we filter only for dynamic) @@ -42,31 +86,33 @@ public enum BlurAlgorithm public HDShadowAtlas() {} - public virtual void InitAtlas(RenderPipelineResources renderPipelineResources, RenderGraph renderGraph, bool useSharedTexture, int width, int height, int atlasShaderID, Material clearMaterial, int maxShadowRequests, HDShadowInitParameters initParams, BlurAlgorithm blurAlgorithm = BlurAlgorithm.None, FilterMode filterMode = FilterMode.Bilinear, DepthBits depthBufferBits = DepthBits.Depth16, RenderTextureFormat format = RenderTextureFormat.Shadowmap, string name = "") + public virtual void InitAtlas(HDShadowAtlasInitParameters initParams) { - this.width = width; - this.height = height; - m_FilterMode = filterMode; - m_DepthBufferBits = depthBufferBits; - m_Format = format; - m_Name = name; + this.width = initParams.width; + this.height = initParams.height; + m_FilterMode = initParams.filterMode; + m_DepthBufferBits = initParams.depthBufferBits; + m_Format = initParams.format; + m_Name = initParams.name; // With render graph, textures are "allocated" every frame so we need to prepare strings beforehand. m_MomentName = m_Name + "Moment"; m_MomentCopyName = m_Name + "MomentCopy"; m_IntermediateSummedAreaName = m_Name + "IntermediateSummedArea"; m_SummedAreaName = m_Name + "SummedAreaFinal"; - m_AtlasShaderID = atlasShaderID; - m_ClearMaterial = clearMaterial; - m_BlurAlgorithm = blurAlgorithm; - m_RenderPipelineResources = renderPipelineResources; + m_AtlasShaderID = initParams.atlasShaderID; + m_ClearMaterial = initParams.clearMaterial; + m_BlurAlgorithm = initParams.blurAlgorithm; + m_RenderPipelineResources = initParams.renderPipelineResources; m_IsACacheForShadows = false; - InitializeRenderGraphOutput(renderGraph, useSharedTexture); + m_GlobalConstantBuffer = initParams.cb; + + InitializeRenderGraphOutput(initParams.renderGraph, initParams.useSharedTexture); } - public HDShadowAtlas(RenderPipelineResources renderPipelineResources, RenderGraph renderGraph, bool useSharedTexture, int width, int height, int atlasShaderID, Material clearMaterial, int maxShadowRequests, HDShadowInitParameters initParams, BlurAlgorithm blurAlgorithm = BlurAlgorithm.None, FilterMode filterMode = FilterMode.Bilinear, DepthBits depthBufferBits = DepthBits.Depth16, RenderTextureFormat format = RenderTextureFormat.Shadowmap, string name = "") + public HDShadowAtlas(HDShadowAtlasInitParameters initParams) { - InitAtlas(renderPipelineResources, renderGraph, useSharedTexture, width, height, atlasShaderID, clearMaterial, maxShadowRequests, initParams, blurAlgorithm, filterMode, depthBufferBits, format, name); + InitAtlas(initParams); } public void UpdateSize(Vector2Int size) @@ -125,6 +171,7 @@ static void RenderShadows(in RenderShadowsParameters parameters, ShadowDrawingSettings shadowDrawSettings, ScriptableRenderContext renderContext, bool renderingOnAShadowCache, + ConstantBuffer constantBuffer, CommandBuffer cmd) { cmd.SetRenderTarget(atlasRenderTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); @@ -175,7 +222,7 @@ static void RenderShadows(in RenderShadowsParameters parameters, globalCB._ViewProjMatrix = viewProjection; globalCB._InvViewProjMatrix = viewProjection.inverse; - ConstantBuffer.PushGlobal(cmd, globalCB, HDShaderIDs._ShaderVariablesGlobal); + constantBuffer.PushGlobal(cmd, globalCB, HDShaderIDs._ShaderVariablesGlobal); cmd.SetGlobalVectorArray(HDShaderIDs._ShadowFrustumPlanes, shadowRequest.frustumPlanes); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.RenderGraph.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.RenderGraph.cs index d30dcd0bc01..37fc0eb0335 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.RenderGraph.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.RenderGraph.cs @@ -270,6 +270,8 @@ class RenderShadowsPassData public TextureHandle intermediateSummedAreaTexture; public TextureHandle summedAreaTexture; + public ConstantBuffer constantBuffer; + public RenderShadowsParameters parameters; public ShadowDrawingSettings shadowDrawSettings; @@ -290,6 +292,7 @@ internal TextureHandle RenderShadows(RenderGraph renderGraph, CullingResults cul passData.shadowDrawSettings = new ShadowDrawingSettings(cullResults, 0); passData.shadowDrawSettings.useRenderingLayerMaskTest = frameSettings.IsEnabled(FrameSettingsField.LightLayers); passData.isRenderingOnACache = m_IsACacheForShadows; + passData.constantBuffer = m_GlobalConstantBuffer; if (passData.parameters.blurAlgorithm == BlurAlgorithm.EVSM) { @@ -319,6 +322,7 @@ internal TextureHandle RenderShadows(RenderGraph renderGraph, CullingResults cul data.shadowDrawSettings, context.renderContext, data.isRenderingOnACache, + data.constantBuffer, context.cmd); if (data.parameters.blurAlgorithm == BlurAlgorithm.EVSM) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs index b9c7de23480..c8576a96e01 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs @@ -298,6 +298,8 @@ partial class HDShadowManager Material m_BlitShadowMaterial; MaterialPropertyBlock m_BlitShadowPropertyBlock = new MaterialPropertyBlock(); + ConstantBuffer m_GlobalShaderVariables; + public static HDCachedShadowManager cachedShadowManager { get { return HDCachedShadowManager.instance; } } public void InitShadowManager(RenderPipelineResources renderPipelineResources, HDShadowInitParameters initParams, RenderGraph renderGraph, Shader clearShader) @@ -321,27 +323,70 @@ public void InitShadowManager(RenderPipelineResources renderPipelineResources, H m_ShadowRequests = new HDShadowRequest[initParams.maxShadowRequests]; m_CachedDirectionalShadowData = new HDDirectionalShadowData[1]; // we only support directional light shadow + m_GlobalShaderVariables = new ConstantBuffer(); + for (int i = 0; i < initParams.maxShadowRequests; i++) { m_ShadowResolutionRequests[i] = new HDShadowResolutionRequest(); } + + HDShadowAtlas.HDShadowAtlasInitParameters punctualAtlasInitParams = new HDShadowAtlas.HDShadowAtlasInitParameters(renderPipelineResources, renderGraph, useSharedTexture: false, initParams.punctualLightShadowAtlas.shadowAtlasResolution, + initParams.punctualLightShadowAtlas.shadowAtlasResolution, HDShaderIDs._ShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, m_GlobalShaderVariables); + punctualAtlasInitParams.name = "Shadow Map Atlas"; + // The cascade atlas will be allocated only if there is a directional light - m_Atlas = new HDDynamicShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: false, initParams.punctualLightShadowAtlas.shadowAtlasResolution, initParams.punctualLightShadowAtlas.shadowAtlasResolution, - HDShaderIDs._ShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, depthBufferBits: initParams.punctualLightShadowAtlas.shadowAtlasDepthBits, name: "Shadow Map Atlas"); + m_Atlas = new HDDynamicShadowAtlas(punctualAtlasInitParams); // Cascade atlas render texture will only be allocated if there is a shadow casting directional light HDShadowAtlas.BlurAlgorithm cascadeBlur = GetDirectionalShadowAlgorithm() == DirectionalShadowAlgorithm.IMS ? HDShadowAtlas.BlurAlgorithm.IM : HDShadowAtlas.BlurAlgorithm.None; - m_CascadeAtlas = new HDDynamicShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: false, 1, 1, HDShaderIDs._ShadowmapCascadeAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, cascadeBlur, depthBufferBits: initParams.directionalShadowsDepthBits, name: "Cascade Shadow Map Atlas"); + + HDShadowAtlas.HDShadowAtlasInitParameters dirAtlasInitParams = punctualAtlasInitParams; + dirAtlasInitParams.useSharedTexture = false; + dirAtlasInitParams.width = 1; + dirAtlasInitParams.height = 1; + dirAtlasInitParams.atlasShaderID = HDShaderIDs._ShadowmapCascadeAtlas; + dirAtlasInitParams.blurAlgorithm = cascadeBlur; + dirAtlasInitParams.depthBufferBits = initParams.directionalShadowsDepthBits; + dirAtlasInitParams.name = "Cascade Shadow Map Atlas"; + + m_CascadeAtlas = new HDDynamicShadowAtlas(dirAtlasInitParams); + + HDShadowAtlas.HDShadowAtlasInitParameters areaAtlasInitParams = punctualAtlasInitParams; if (ShaderConfig.s_AreaLights == 1) - m_AreaLightShadowAtlas = new HDDynamicShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: false, initParams.areaLightShadowAtlas.shadowAtlasResolution, initParams.areaLightShadowAtlas.shadowAtlasResolution, - HDShaderIDs._ShadowmapAreaAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, HDShadowAtlas.BlurAlgorithm.EVSM, depthBufferBits: initParams.areaLightShadowAtlas.shadowAtlasDepthBits, name: "Area Light Shadow Map Atlas"); + { + areaAtlasInitParams.useSharedTexture = false; + areaAtlasInitParams.width = initParams.areaLightShadowAtlas.shadowAtlasResolution; + areaAtlasInitParams.height = initParams.areaLightShadowAtlas.shadowAtlasResolution; + areaAtlasInitParams.atlasShaderID = HDShaderIDs._ShadowmapAreaAtlas; + areaAtlasInitParams.blurAlgorithm = HDShadowAtlas.BlurAlgorithm.EVSM; + areaAtlasInitParams.depthBufferBits = initParams.areaLightShadowAtlas.shadowAtlasDepthBits; + areaAtlasInitParams.name = "Area Light Shadow Map Atlas"; - cachedShadowManager.InitPunctualShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: true, initParams.cachedPunctualLightShadowAtlas, initParams.cachedPunctualLightShadowAtlas, - HDShaderIDs._CachedShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams: initParams, depthBufferBits: initParams.punctualLightShadowAtlas.shadowAtlasDepthBits, name: "Cached Shadow Map Atlas"); + + m_AreaLightShadowAtlas = new HDDynamicShadowAtlas(areaAtlasInitParams); + } + + HDShadowAtlas.HDShadowAtlasInitParameters cachedPunctualAtlasInitParams = punctualAtlasInitParams; + cachedPunctualAtlasInitParams.useSharedTexture = true; + cachedPunctualAtlasInitParams.width = initParams.cachedPunctualLightShadowAtlas; + cachedPunctualAtlasInitParams.height = initParams.cachedPunctualLightShadowAtlas; + cachedPunctualAtlasInitParams.atlasShaderID = HDShaderIDs._CachedShadowmapAtlas; + cachedPunctualAtlasInitParams.name = "Cached Shadow Map Atlas"; + + + cachedShadowManager.InitPunctualShadowAtlas(cachedPunctualAtlasInitParams); if (ShaderConfig.s_AreaLights == 1) - cachedShadowManager.InitAreaLightShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: true, initParams.cachedAreaLightShadowAtlas, initParams.cachedAreaLightShadowAtlas, - HDShaderIDs._CachedAreaLightShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams: initParams, HDShadowAtlas.BlurAlgorithm.EVSM, depthBufferBits: initParams.areaLightShadowAtlas.shadowAtlasDepthBits, name: "Cached Area Light Shadow Map Atlas"); + { + HDShadowAtlas.HDShadowAtlasInitParameters cachedAreaAtlasInitParams = areaAtlasInitParams; + areaAtlasInitParams.useSharedTexture = true; + areaAtlasInitParams.width = initParams.cachedAreaLightShadowAtlas; + areaAtlasInitParams.height = initParams.cachedAreaLightShadowAtlas; + areaAtlasInitParams.atlasShaderID = HDShaderIDs._CachedAreaLightShadowmapAtlas; + areaAtlasInitParams.name = "Cached Area Light Shadow Map Atlas"; + + cachedShadowManager.InitAreaLightShadowAtlas(cachedAreaAtlasInitParams); + } } public void Cleanup(RenderGraph renderGraph) @@ -359,6 +404,8 @@ public void Cleanup(RenderGraph renderGraph) CoreUtils.Destroy(m_ClearShadowMaterial); cachedShadowManager.Cleanup(renderGraph); + + m_GlobalShaderVariables.Release(); } // Keep in sync with both HDShadowSampling.hlsl