I wanted to provoke a synchronization validation error by setting all the external subpass dependencies of stages and memory accesses to NONE
, but I do not get synchronization validation errors. Why not?
Here’s my setup as captured with RenderDoc:
vkCmdBeginRenderPass(C=Clear, D=Clear) // using RP#1
vkCmdDrawIndexed(....) // several of these
vkCmdEndRenderPass(C=Store, D=Store)
vkCmdBeginRenderPass(C=Load, D=Load) // using RP#2
vkCmdDrawIndexed(...)
vkCmdEndRenderPass(C=Store, D=Store)
Both render passes use the same color C
and depth D
attachment images (i.e., 2 attachments in total). Each render pass has one single subpass.
Subpass dependencies of RP#1 are as follows:
dependencyCount 2
pDependencies VkSubpassDependency2[2]
[0] VkSubpassDependency2()
sType VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2
pNext NULL
srcSubpass UINT32_MAX
dstSubpass 0
srcStageMask VK_PIPELINE_STAGE_NONE
dstStageMask VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
srcAccessMask VK_ACCESS_NONE
dstAccessMask VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
dependencyFlags VkDependencyFlagBits(0)
viewOffset 0
[1] VkSubpassDependency2()
sType VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2
pNext NULL
srcSubpass 0
dstSubpass UINT32_MAX
srcStageMask VK_PIPELINE_STAGE_NONE
dstStageMask VK_PIPELINE_STAGE_NONE
srcAccessMask VK_ACCESS_NONE
dstAccessMask VK_ACCESS_NONE
dependencyFlags VkDependencyFlagBits(0)
viewOffset 0
Its C
and D
layouts are specified as follows (initial → subpass 0 → final), respectively:
VK_IMAGE_LAYOUT_UNDEFINED -> VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL -> VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
VK_IMAGE_LAYOUT_UNDEFINED -> VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
Subpass dependencies of RP#2 are as follows:
dependencyCount 2
pDependencies VkSubpassDependency2[2]
[0] VkSubpassDependency2()
sType VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2
pNext NULL
srcSubpass UINT32_MAX
dstSubpass 0
srcStageMask VK_PIPELINE_STAGE_NONE
dstStageMask VK_PIPELINE_STAGE_NONE
srcAccessMask VK_ACCESS_NONE
dstAccessMask VK_ACCESS_NONE
dependencyFlags VkDependencyFlagBits(0)
viewOffset 0
[1] VkSubpassDependency2()
sType VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2
pNext NULL
srcSubpass 0
dstSubpass UINT32_MAX
srcStageMask VK_PIPELINE_STAGE_NONE
dstStageMask VK_PIPELINE_STAGE_NONE
srcAccessMask VK_ACCESS_NONE
dstAccessMask VK_ACCESS_NONE
dependencyFlags VkDependencyFlagBits(0)
viewOffset 0
Its C
and D
layouts are specified as follows (initial → subpass 0 → final), respectively:
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL -> VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL -> VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
Note:
I know that synchronization validation is working because if I change the first subpass dependency to all VK_PIPELINE_STAGE_NONE
and VK_ACCESS_NONE
, then I get the following validation error due to the layout transition hazard:
Validation Error: [ SYNC-HAZARD-WRITE_AFTER_WRITE ] Object 0: handle = 0x12fb2600000002c0, 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.
Question:
But if I leave the subpass dependencies like stated above, I would definitely also expect a SYNC-HAZARD-WRITE_AFTER_WRITE
because RP#2 writes into the same attachments as RP#1.
The layout stays the same, so no layout transition has to be performed, but I would say that there would still have to be a synchronization validation error complaining about the fact that RP#2 does not wait for RP#1 to finish its depth and color writes. Why doesn’t it complain?
RP#2 races RP#1, doesn’t it? Do I overlook something here?