So I have a render pass with a single subpass that draws directly to a framebuffer. The specification doesn't force me to use dependencies - if I omit them, the implementation inserts them implicitly (though I don't understand why it uses srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
for the first subpass - this stage means the very beginning, i.e. don't wait for anything).
But as usual with the Vulkan - better to be explicit. And here is the confusion - multiple sources use subpasses differently.
Sdk's cube example does not use them at all.
Vulkan-tutorial uses only one:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = 0; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
Why
srcAccessMask
is zero here?API without secrets uses two:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
and
dependency.srcSubpass = 0; dependency.dstSubpass = VK_SUBPASS_EXTERNAL; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
It's not very clear why
srcStageMask
isVK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
in the first subpass - isn't this stage should be used for execution dependencies, but here we need a memory dependency? The same question about whydstStageMask
isVK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
in the second subpass?Khronos synchronization examples uses one:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = 0; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
Why
srcAccessMask
is 0?And here's my attempt with two dependencies:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // need to wait until presentation is finished reading the image dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to the image in this stage dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; and dependency.srcSubpass = 0; dependency.dstSubpass = VK_SUBPASS_EXTERNAL; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to the image in this stage dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // presentation reads image in this stage (is it?) dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
All this is very confusing. As you can see multiple competent sources have a different vision. Which one to use? How to understand these dependencies?