Search code examples
imagetexturesvulkandepth-buffer

Multiple attachment layout transitions via VkSubpassDependency


I'm trying to figure out how to use VkSubpassDependency to account for multiple attachment layout transitions (especially those of different types). I see a Sascha Willems example on how to use access masks in the subpass dependency to create an image layout transition to the final layout, but Sascha only uses a single attachment. In my situation I have multiple attachments, one for the color, one for the depth, each with a different final transition. Do I just shove more access mask bits in? from the spec, it looks like I would actually have to create a new subpass dependency with stage masks on a different part of the pipeline that involves color.

Any synchronization command that takes both stage masks and access masks uses both to define the access scopes - only the specified access types performed by the specified stages are included in the access scope. An application must not specify an access flag in a synchronization command if it does not include a pipeline stage in the corresponding stage mask that is able to perform accesses of that type.

I can't find any examples of this, and I don't see this outlined anywhere.


Solution

  • Access masks do not correlate to layout transitions. For render passes, you don't specify layout transitions explicitly for attachments. You instead define, in the VkAttachmentReferences provided to a VkSubpassDescription, which layout the attachment(s) shall be in for that subpass. The render pass system is then responsible for inserting appropriate transitions inbetween the various subpasses, depending entirely on the order in which it chooses to execute the subpasses.

    An order that is informed by subpass execution dependencies, of course. As such, the quote from a comment in the example, "Use subpass dependencies for layout transitions" is rather misleading. It's not the subpass dependencies that cause layout transitions; it's the render pass system. It's just that the subpass dependencies provide constraints on how the render pass can inject a layout transition.

    Now, those constraints do matter, because while render passes are more automatic, Vulkan is still Vulkan. Without explicit dependencies between subpasses, they may execute in any order. So if one subpass is going to use the rendering products of another one, even if it is just overwriting those rendering products, there must still be a dependency between them.

    The access masks are important, but not for layout transitions. They're important for proper synchronization; they're important for ensuring that the source subpass has made the proper operations visible to the destination subpass.

    So, if subpass 0 writes to the color and depth buffers, but subpass 1 only cares about the values written to the depth buffer, the dependency between them only needs to say that it will access the written depth information (and of course, how it plans to read it).