It is partly the Specification’s fault. For a long time the Synchronization was described quite badly. Then there were series of updates. For better or worse the Specification is a living document. It receives updates frequently. And yea, there are still problematic areas, and horde of obscure corner-cases nobody had time to think through.
Anyway at that point it was not clear what access flags should be used. And even some in-spec examples used non-zero flags where zero would suffice. From that the Validation Layers oftentimes forced people to use non-zero flags. Materials were written using non-zero flags. Rest is inertia.
The situation is 0
access flag makes sense sometimes, and non-zero flags are allowed (and should not be harmful; I think, unless Validation Layers became stricter in the meantime) – some may consider it easier to read and less error prone.
BTW as for external materials… I am not sure if I am being unortodox here, but I would think their job is to get someone up to speed. Specifications job is to get someone do things correctly. So I would say the external materials only need to get you ready to read the spec. From that point only spec should be used, and if you are confused about something in this autoritative document, then probably others are too, and you should submit an Issue (or PR). I don’t think many people think the same way, as there are not that many contributors to the repo compared to how many there must be Vulkan users.
Anyway that is a long introduction to basically me saying “read the spec”. Synchronization is, I think, exactly the one thing you do not want to learn from third-party. Third-party may explain it deceptively easily (but in the long run more formal, but potentially harder to read description is better).
Now, to reasoning for the above code snippet (and it may be wrong, because I pulled it outa my ass, or because I misunderstood your situation):
I probably confused you with the Dependency Chaining. It should be equivalent to a single Dependency, which should have non-zero access flags (I provided this alternative in the original thread).
At the risk of being another third-party explaining things, the Specification explains Memory Dependencies in terms of Availability and Visibility. Specific state of the memory location (i.e. the modification by a write) must be made Available From the source. And it must be made Visible To the destination.
To make things harder, Availability and Visibility happen as another operation on the Queue (and need to be synchronized too, in a way). Only state of memory that is Available From can become Visible To.
So, the above is valid.
The first dependency makes memory Available From the source. The Availability Op Happens-Before VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
(i.e. dstStage
). I use that stage only as a Chaining stage, and it even cannot access memory, so the Access Flags is 0
.
The second dependency has Execution Dependency on VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
. That means the Availability Op has finished before the Dependency does anything else. That stage still cannot do anything with memory so Access Flags is still 0
. Then the dependency takes any Available memory and makes it Visible To the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_BIT
.