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