Skip to content

Commit 3f155d0

Browse files
arttu-peltonenEvergreen
authored andcommitted
Fix Vulkan validation errors in URP CopyDepthPass
This PR fixes https://jira.unity3d.com/browse/UUM-60387 The bug requires a few things to be true in order to reproduce: have URP with RenderGraph enabled, use Vulkan, have MSAA disabled. In this case, when the two repro projects were set up in a way that causes CopyDepthPass to be executed (specifically with CopyToDepth=false), the depth was not getting copied correctly, causing subsequent depth tests to fail, resulting in missing objects. When Vulkan validation layers were enabled, the following error was output: ``` VULKAN: VALIDATION ERROR: Validation Error: [ VUID-vkCmdDraw-None-06886 ] Object 0: handle = 0xab7c3f0000001d62, type = VK_OBJECT_TYPE_PIPELINE; Object 1: handle = 0xceb68d0000001d60, name = ExecuteRenderGraph (C0:C/S, C1:L/S, DS:L/S), type = VK_OBJECT_TYPE_RENDER_PASS; Object 2: handle = 0x14239304030, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xf157442b | vkCmdDraw: depthWriteEnable is VK_TRUE, while the layout (VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) of the depth aspect of the depth/stencil attachment in the render pass is read only. The Vulkan spec states: If the current render pass instance uses a depth/stencil attachment with a read-only layout for the depth aspect, depth writes must be disabled (https://vulkan.lunarg.com/doc/view/1.3.243.0/windows/1.3-extensions/vkspec.html#VUID-vkCmdDraw-None-06886) CommandBuffer labels: CopyDepth | CopyDepthPass Objects: #0: { type = VK_OBJECT_TYPE_PIPELINE, handle = 0xab7c3f0000001d62 } #1: { name = ExecuteRenderGraph (C0:C/S, C1:L/S, DS:L/S), type = VK_OBJECT_TYPE_RENDER_PASS, handle = 0xceb68d0000001d60 } #2: { type = VK_OBJECT_TYPE_COMMAND_BUFFER, handle = 0x14239304030 } ``` The reason for this error is that the render state is being setup in an inconsistent way: - `depthWriteEnable=true` because `CopyDepth.shader` contains `ZWrite On`, but - because we don't bind a depth attachment, the RenderGraph compiler sets `SubPassFlags.ReadOnlyDepth` flag which causes Vulkan backend to use the `VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL` layout. To fix this conflicting setup we set ZWrite to On/Off depending on whether depth output is active or not. This fixes the validation error, and the incorrect rendering in the original repro project, and makes the new graphics test pass. Shoutout to @eduardas-vitkus for creating the new graphics test that catches this specific case, and providing a ton of relevant information on the issue, including the Vulkan validation error!
1 parent fd01370 commit 3f155d0

17 files changed

+1460
-34
lines changed

Packages/com.unity.render-pipelines.universal/Runtime/Passes/CopyDepthPass.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class CopyDepthPass : ScriptableRenderPass
2727
internal bool m_ShouldClear;
2828
private PassData m_PassData;
2929

30+
static readonly int k_ZWriteShaderHandle = Shader.PropertyToID("_ZWrite");
31+
3032
/// <summary>
3133
/// Creates a new <c>CopyDepthPass</c> instance.
3234
/// </summary>
@@ -98,6 +100,7 @@ private class PassData
98100
internal int msaaSamples;
99101
internal bool copyResolvedDepth;
100102
internal bool copyToDepth;
103+
internal int zWriteShaderHandle;
101104
}
102105

103106
/// <inheritdoc/>
@@ -178,10 +181,9 @@ private static void ExecutePass(RasterCommandBuffer cmd, PassData passData, RTHa
178181
break;
179182
}
180183

181-
if (copyToDepth || destination.rt.graphicsFormat == GraphicsFormat.None)
182-
cmd.SetKeyword(ShaderGlobalKeywords._OUTPUT_DEPTH, true);
183-
else
184-
cmd.SetKeyword(ShaderGlobalKeywords._OUTPUT_DEPTH, false);
184+
bool outputDepth = copyToDepth || destination.rt.graphicsFormat == GraphicsFormat.None;
185+
cmd.SetKeyword(ShaderGlobalKeywords._OUTPUT_DEPTH, outputDepth);
186+
copyDepthMaterial.SetFloat(k_ZWriteShaderHandle, outputDepth ? 1.0f : 0.0f);
185187

186188
Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
187189
// We y-flip if

Packages/com.unity.render-pipelines.universal/Shaders/Utils/CopyDepth.shader

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ Shader "Hidden/Universal Render Pipeline/CopyDepth"
77
Pass
88
{
99
Name "CopyDepth"
10-
ZTest Always ZWrite On ColorMask R
10+
ZTest Always
11+
ZWrite[_ZWrite]
12+
ColorMask R
1113
Cull Off
1214

1315
HLSLPROGRAM

Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/311_DepthCopyTransparent.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)