So there is this official example https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#combined-graphicspresent-queue:
/* Only need a dependency coming in to ensure that the first
layout transition happens at the right time.
Second external dependency is implied by having a different
finalLayout and subpass layout. */
VkSubpassDependency dependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
// .srcStageMask needs to be a part of pWaitDstStageMask in the WSI semaphore.
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dependencyFlags = 0};
Could someone please provide me with relevant sections in the specification that combined guarantee (constitute a chain of reasoning) that with such a dependency layout transition will happen not until the queue's wait semaphore (image acquired) is signaled?
Particularly I can't find how to interpret this "dependency from that same stage to itself".
To be clear. I've found a lot of places that seem to be relevant here. I'm reading docs for over a month now but I'm struggling to find coherence in them.
For example when (according to the specification) an availability operation does happen? When relevant memory dependency operation was submitted (as in submission order)? If yes than when the subpass dependency is submitted? Or is it somewhere between source scope instructions and destination scope instruction (like in If srcSubpass is equal to VK_SUBPASS_EXTERNAL, the first synchronization scope includes commands that occur earlier in submission order than the vkCmdBeginRenderPass). And if yes what instructions the srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT in the above example is referring to?
EDIT after krOoze's answer
I thought I'll write here. One because it's too long for a comment and two because I believe it may be useful for others.
I admit, I misinterpreted the part about the execution dependency chain in the spec.
So to sum it up. To define the mechanism in question in terms of the Specification we have what follows:
The waiting on semaphore operation happens-before the subpass dependency operation (here I have some trouble actually):
6.4.2. Semaphore Waiting*
The semaphore wait operation happens-after the first set of operations in the execution dependency, and happens-before the second set of operations in the execution dependency.But how to be sure that our subpass dependency operation is in the second set? It is in the same batch, it doesn't have defined submission order with regard to a subpass dependency (at least I cannot see one) and the definition of the semaphore second synchronisation scope isn't helpful because our subpass dependency doesn't happen on the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage (and it's the limitation of the second synchronisation scope in case of vkQueueSubmit). What's more synchronisation scope doesn't define the second set of operations anyway. It's a distinct term. But I've found one more statement that may be helpful here (well, if we'll agree that a subpass dependency is a part of a work item):
4.3.5. Queue Submission
Each batch consists of three distinct parts:- Zero or more semaphores to wait on before execution of the rest of the batch.
- Zero or more work items to execute.
- Zero or more semaphores to signal upon completion of the work items.
And we need to be sure of this ordering to construct the execution dependency chain:
Waiting on the semaphore and the subpass dependency constitute an execution dependency chain according to:
6.1. Execution and Memory Dependencies
An execution dependency chain is a sequence of execution dependencies that form a happens-before relation between the first dependency’s A' and the final dependency’s B'. For each consecutive pair of execution dependencies, a chain exists if the intersection of BS in the first dependency and AS in the second dependency is not an empty set.(see krOoze's answer for details)
From this we know that the destination scope of our subpass dependency will happen-after signaling the semaphore (a signal operation is in the source scope of the semaphore wait operation).
Now we should be fine with the layout transition rule:Layout transition happens-after the availability operation for our subpass dependency:
7.1. Render Pass Creation
Automatic layout transitions away from initialLayout happens-after the availability operations for all dependencies with a srcSubpass equal to VK_SUBPASS_EXTERNAL, where dstSubpass uses the attachment that will be transitioned.To be honest I'm still missing the ordering between signaling the semaphore and the availability operation part in the spec but I think it could be assumed.
(the above would work because an availability operation is part of the memory dependency operation:An operation that performs a memory dependency generates:
• An availability operation with source scope of all writes in the first access scope of the dependency and a destination scope of the device domain.well our first access scope is empty but still it's an availability operation, right?)
There's also this statement:
For attachments however, subpass dependencies work more like a VkImageMemoryBarrier defined similarly to the VkMemoryBarrier above, the queue family indices set to VK_QUEUE_FAMILY_IGNORED, and layouts as follows:
• The equivalent to oldLayout is the attachment’s layout according to the subpass description for srcSubpass.
• The equivalent to newLayout is the attachment’s layout according to the subpass description for dstSubpass.
...which brings another scope to analyse but my head aches already. I'll be more than happy to edit this more when I got some review of the above thoughts.
*All the spec quotes from "Vulkan® 1.2.132 - A Specification (with all registered Vulkan extensions)"
