I have a very simple setup - in fact one of the earlier stages of vkguide.dev. So a single render pass with a single subpass. Those have one color and one depth attachment.
The color AttachmentDescription has .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED and .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR. In its SubPassDescription, it has .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
The depth AttachmentDescription has .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED and .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL. In its SubPassDescription, it has .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL.
I'm trying to understand the subpass dependencies, so I don't want to rely on the implicit ones the spec provides but provide my own, minimal ones.
When I provide "zeroed out" subpass dependencies, I get a the following error with sync validation turned on:
Validation Error: [ SYNC-HAZARD-WRITE_AFTER_WRITE ] Object 0: handle = 0x83d4ee000000000b, type = VK_OBJECT_TYPE_RENDER_PASS; | MessageID = 0xfdf9f5e1 | vkCmdBeginRenderPass: Hazard WRITE_AFTER_WRITE vs. layout transition in subpass 0 for attachment 1 aspect depth during load with loadOp VK_ATTACHMENT_LOAD_OP_CLEAR.
So he's complaining about the depth attachment (attachment 1). And I can fix this with the following set of explicit subpass dependencies:
constexpr VkSubpassDependency in_dependency{
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
};
constexpr VkSubpassDependency out_dependency = {
.srcSubpass = 0,
.dstSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
.srcAccessMask = 0,
.dstAccessMask = 0,
.dependencyFlags = 0
};
The second of course is only there to not use the second implicit one and does nothing. The first one is an explicit dependency between things before the renderpass and the first/only subpass. But I don't really understand - a couple of questions:
- does a
srcAccessMask = 0really define a real dependency? it's empty after all, or are things different with aVK_SUBPASS_EXTERNAL? - Why do I only need a dependency on the depth- and not on the color attachment?
I made the image below and am aware that color attachment gets loaded and stored in the same pipeline stage, and that the depth attachment does now. However I still don't understand why that eliminates the need for a dependency. That pipeline stage could still overlap between two renderpasses right?
