Possible mistake in official synchronization2 example

Hi, I’m new to this forum and to Vulkan, but hopefully this question makes sense.

I’ve been recently focusing on the synchronization aspect of the API, in particular for the synchronization2 extension, and I’ve stumbled upon the official examples here.

Now, the specific example that’s giving me trouble is the one about syncing swapchain acquire - render - present on a single, combined, queue (this one). I’ll start by saying that I think I understand the variant of this scenario that doesn’t use synchronization2.

The problem to me is that the automatic layout transition of the swapchain image away from ATTACHMENT_OPTIMAL and into PRESENT_SRC_KHR is not synchronized with the renderingCompleteSemaphore.

The example says:

Normally, we would need an external dependency at the end as well since we are changing layout in finalLayout,
but since we are signalling a semaphore, we can rely on Vulkan's default behavior,
which injects an external dependency here with
dstStageMask = VK_PIPELINE_STAGE_NONE_KHR,
dstAccessMask = VK_ACCESS_NONE_KHR.

which I would agree with normally, but synchronization2 introduced the possibility to specify a stageMask for a queue submit semaphore signal operation, which critically in this case is set to COLOR_ATTACHMENT_OUTPUT:

VkSemaphoreSubmitInfoKHR renderingCompleteInfo = {
    ...
    .semaphore = renderingCompleteSemaphore,
    .stageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR};

VkSubmitInfo2KHR submitInfo = {
    ...
    .waitSemaphoreInfoCount     = 1,
    .pWaitSemaphoreInfos        = &acquireCompleteInfo,
    ...
    .signalSemaphoreInfoCount   = 1,
    .pSignalSemaphoreInfos      = &renderingCompleteInfo};

(the same renderingCompleteSemaphore signal event is then used as a first synchronization scope for the QueuePresent operation).

It is my understanding that, since the second synchronization scope of the implicit exit subpass dependency is defined as stage NONE (the former BOTTOM_OF_PIPE), and the semaphore signal operation’s first synchronization scope has been set to stage COLOR_ATTACHMENT_OUTPUT (and any logically prior stages), there exists no dependency chain between the two, as the intersection between the synchronization scopes is empty.

This would then mean that it’s possible the swapchain image is transitioned to SRC_PRESENT_KHR after the renderingCompleteSemaphore is signaled.

Please note that, without synchronization2, the equivalent queue submit’s semaphore signal’s stageMask would correctly be BOTTOM_OF_PIPE, which would indeed form a dependency chain and the problem wouldn’t exist.

So, is this actually a mistake in the official example or am I missing something?

Thanks either way

Looks like a copy-paste error. Why don’t you open a ticket on the example repo?

Well, as I said I’m new to Vulkan and I wasn’t sure I understood this topic well enough, this question was very helpful to validate my knowledge on this matter.
But now that you confirm this is probably a typo I’ll open an issue in the github repo

Thanks