Is the Vulkan subpass dependency per framebuffer?

Viewed 41

I am following Overvoorde's Vulkan tutorial. When we wait for the acquired image we wait before the color output stage and we don't want to transition the layout of that image before it is available, so we do this:

srcSubpass = VK_SUBPASS_EXTERNAL;
dstSubpass = 0;
srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
srcAccessMask = 0
dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.

Which is also described in the specs here: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#synchronization-semaphores-waiting

  1. My question is, are we waiting for all previous render passes to be done with their color output stage? Or does the driver know to wait only for the render passes that operate on the image we are operating on?

We could have acquired an image that finished its color output stage long ago but there may still be previously submitted render passes working on other images.

So, does this subpass dependency make us wait for all previous render passes or does it know that the render pass previously working on our image is done and the transition can happen immediately.

  1. What is the color output stage, does include the presentation. When is the color output stage finished?
1 Answers

I am gonna assume you generally understand why this is in the code. Otherwise there are some duplicate Q&As for that, such as "Synchronizing" a render pass layout transition with a semaphore in Acquire-Present scenario in Vulkan or Use of VkSubpassDependency vs semaphore?

  1. Vulkan specification is very specific on what the synchronization scopes are:

    If srcSubpass is equal to VK_SUBPASS_EXTERNAL, the first synchronization scope includes commands that occur earlier in submission order than the vkCmdBeginRenderPass used to begin the render pass instance. [...] the first synchronization scope is limited to operations on the pipeline stages determined by the source stage mask specified by srcStageMask.

    So, you take all operations earlier in submission order up from the vkCmdBeginRenderPass and filter them only by pipeline stage.

    "Submission order" here means pretty much everything recorded and submitted by vkQueueSubmit before. So formally that does form an execution dependency with any previous render pass instances. Only way around that is if the drivers made use of the "as-if" principle.

    The access mask is 0, therefore there is no memory dependency on any images or buffers, and so this particular Subpass Dependency does not know if all previous uses of the image are finished. It requires to be handed an image that is already in available-from state (such as ensured by the semaphore signal and subsequent wait).

  2. No pipeline stage includes presentation. Only the Fence or Semaphore from vkAcquireNextImageKHR with the specific image index says when presentation is finished with the image.

    Stages are never "finished". It is a Pipeline not a Finite State Machine. It is the same as asking for natural gas pipeline when is the Uzhorod station finished. It is not a valid question, so it is unanswerable.

    The color output stage is what the specification say it is. It is part of the Graphics Pipeline. Varied queue operations require to do work in it, such as vkCmdDraw* color attachment writes, subpass load\store ops, subpass resolve ops, and vkCmdClearAttachments, and possibly more in the future.

Related