Synchronization between seperate renderpasses

There are some misunderstandings.

Firstly my surprise about Write-after-Write situation is that it is wasteful. If you write something, and then write it again, you computed the original write for nothing (as nobody have ever read it). This general situation should not arise often… then again it is the first thing you said that you know your approach is not optimal.

I wasn’t aware the loadOp performed any synchronization… If it does, just setting this would be enough.

It does not (well, it sorta does define some dependency within the subpass; but that was not my point). It is just another Queue Operation that needs to be synchronized against.
The point being, that the specific chosen load\storeOp dictates which Pipeline Stage, and Access mask needs to be provided to the user-defined Dependency.

The implicit subpass dependency doesn’t make sense to me, I wish the documentation would be more clear about it.

It doesn’t have to. It is simply equivalent to the above quoted Dependency. If it confuses you just ignore it and provide your own dependency.

The first barrier has srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, which to me implies “wait for nothing”. How is this useful in this case?

It is probably not. AIS it is always clearer to state things explicitly.
Yes, it “waits for nothing”. But you can chain dependencies, which means you can actually make it wait for something by chaining barrier on TOP if you so choose.

(Assuming two Render Pass Instances directly after each other) I suggest to do:


// Dependency of the first Render Pass Instance
VkSubpassDependency rp1Dependency = {
    .srcSubpass = lastSubpass; // Last subpass color attachment is used in
    .dstSubpass = VK_SUBPASS_EXTERNAL;
    .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_BIT; // matches storeOp on a color attachment
    .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; // to be synchronized later
    .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // matches VK_ATTACHMENT_STORE_OP_STORE
    .dstAccessMask = 0;
};

// Dependency of the second Render Pass Instance
VkSubpassDependency rp2Dependency = {
    .srcSubpass = VK_SUBPASS_EXTERNAL;
    .dstSubpass =  firstSubpass; // First subpass color attachment is used in
    .srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; // chains to rp1Dependency::dstStageMask stage
    .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_BIT; // matches loadOp on a color attachment
    .srcAccessMask = 0;
    .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;  // matches VK_ATTACHMENT_LOAD_OP_LOAD
};

You cannot just provide VK_PIPELINE_STAGE_COLOR_ATTACHMENT_BIT to vkCmdPipelineBarrier. The vkCmdPipelineBarrier Scopes does not cover intenal writes of the Render Pass Instance.