Looking at the vulkan spec after being confused by previous revisions, I saw the following updated clarification of vkCmdPipelineBarrier:
If
vkCmdPipelineBarrierwas recorded outside a render pass instance, the first synchronization scope includes all commands that occur earlier in submission order. IfvkCmdPipelineBarrierwas recorded inside a render pass instance, the first synchronization scope includes only commands that occur earlier in submission order within the same subpass. In either case, the first synchronization scope is limited to operations on the pipeline stages determined by the source stage mask specified bysrcStageMask.If
vkCmdPipelineBarrierwas recorded outside a render pass instance, the second synchronization scope includes all commands that occur later in submission order. IfvkCmdPipelineBarrierwas recorded inside a render pass instance, the second synchronization scope includes only commands that occur later in submission order within the same subpass. In either case, the second synchronization scope is limited to operations on the pipeline stages determined by the destination stage mask specified bydstStageMask.
If I understand correctly, are these statements saying that:
first synchronization scope is the possible commands used for what can be considered for synchronization before (source)
second synchronization scope is the possible commands used for what can be considered for synchronization after (destination)
and that the only thing that changes is that commands in other subpasses are not considered for either synchronization scope when a pipeline barrier is used within a renderpass.
What I'm confused about is the way it is worded made me think that maybe even previous commands, before the render pass were not considered for the first synchronization scope. (same with after for the second)
Are these examples of synchronization correct?
if outside a render pass I do something like:
1. transfer;
2. computeDispatch;
3. beginRenderPass;
...
endRenderPass;
pipelineBarrier(...);
4. computeDispatch;
5. beginRenderPass;
...
endRenderPass;
commands 1, 2, and 3 will be considered in the pipelineBarrier for synchronization before, ie, be in the first synchronization scope, and commands 4, and 5 will be considered afterwards, ie the second synchronization scope.
if I have the following list of commands:
1. transfer;
2. computeDispatch;
3. beginRenderPass;
3.1 next subpass;
3.1.1 bindPipeline;
3.1.2 bindDescriptor;
3.1.3 bindVertexBuffer;
pipelineBarrier(...);
3.1.4 bindIndexBuffer;
3.1.5 drawIndexed;
endRenderPass;
4. computeDispatch;
5. beginRenderPass;
...
endRenderPass;
the commands 1, 2, 3.1.1, 3.1.2 and 3.1.3 will be in the first synchronization scope, and 3.1.4 and 3.1.5, 4, 5 will be in the second.
and finally the bolded section of text is saying that if I do the following:
1. transfer;
2. computeDispatch;
3. beginRenderPass;
3.1 first subpass;
3.1.1 bindPipeline;
3.1.2 bindDescriptors;
3.1.3 bindVertexBuffer;
3.1.4 draw;
3.2 next subpass;
3.2.1 bindPipeline;
3.2.2 bindDescriptor;
3.2.3 bindVertexBuffer;
pipelineBarrier(...);
3.2.4 bindIndexBuffer;
3.2.5 drawIndexed;
3.3 next subpass;
3.3.1 bindPipeline;
3.3.2 bindDescriptors;
3.3.4 draw;
endRenderPass;
4. computeDispatch;
5. beginRenderPass;
...
endRenderPass;
commands 1,2, 3.2.1, 3.2.2, and 3.2.3 will be in the first synchronization scope, and commands 3.2.4, 3.2.5, 4, and 5 will be in the second synchronization scope correct? In other words, other subpasses are not considered for synchronization scopes for pipeline barriers used within a render pass? only the current subpass?