My understanding is that when you submit a vkCmdPipelineBarrier command, then all the commands in the source synchronization scope must reach srcStage before any of the commands in the destination synchronization scope are allowed to begin the dstStage of their pipeline.
But what if srcStageMask specifies a stage which a command in the source synchronization scope doesn't contain? For example, if the command is vkCmdDispatch and srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT.
The spec seems to answer this question:
If a synchronization command includes a source stage mask, its first synchronization scope only includes execution of the pipeline stages specified in that mask
So then I would expect that none of the operations performed by any stages of that command (vkCmdDispatch in the previous example) would be included in the synchronization scope. But in yet another blog explaining Vulkan synchronization, the author says that this produces an execution dependency chain:
1. vkCmdDispatch 2. vkCmdDispatch 3. vkCmdPipelineBarrier(srcStageMask = COMPUTE, dstStageMask = TRANSFER) 4. vkCmdPipelineBarrier(srcStageMask = TRANSFER, dstStageMask = COMPUTE) 5. vkCmdDispatch 6. vkCmdDispatchIn this example we actually get a dependency between {1, 2} and {5, 6}. This is because we created a chain of dependencies between COMPUTE -> TRANSFER -> COMPUTE. When we wait for TRANSFER in 4. we must also wait for anything which is currently blocking TRANSFER.
But the spec says
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.
In the blog post's example, wouldn't BS for the first pipeline barrier be the empty set since vkCmdDispatch doesn't contain a transfer stage? Then the intersection of BS and AS would be the empty set and no dependency chain should exist.
But apparently one does exist, so this lead me to believe that I have an incorrect understanding of what happens when srcStageMask or dstStageMask specifies a stage which is not in the pipeline of a command. So then what does happen?
Edit:
From Nicol's answer:
It was talking specifically about the set of stages involved. Bs lists TRANSFER. As include TRANSFER. The intersection of the two stage masks is TRANSFER and therefore not empty. Therefore, there is a dependency chain.
So then AS = {TRANSFER} union {stages logically earlier than TRANSFER}
and BS = {TRANSFER} union {stages logically later than TRANSFER}?
If this were the case, my confusion would be resolved. But... (From Nicol's answer)
The spec said nothing about what commands get executed.
This seems in contradiction with my interpretation of the spec. Chapter 6.6 says:
If vkCmdPipelineBarrier was recorded outside a render pass instance, the second synchronization scope includes all commands that occur later in submission order.
BS is another name the spec gives for the second synchronization scope. So then BS contains commands, not pipeline stages right? Then how can the TRANSFER stage be in BS?
I don't mean to be pedantic, I am genuinely trying to learn how to interpret the spec and come to this conclusion on my own so that I'm not dependent on stackoverflow.