In a framework I am developing, I want to create default subpass dependencies if none are specified. These default subpass dependencies shall be safe, i.e. ensure the correctness of the application and potentially sacrifice on the performance a bit.
I am thinking of the following default dependencies:
VkSubpassDependency incomingDependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL;
.dstSubpass = firstSubpass;
.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
.dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
.srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;;
.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
.dependencyFlags = 0;
};
VkSubpassDependency outgoingDependency = {
.srcSubpass = lastSubpass;
.dstSubpass = VK_SUBPASS_EXTERNAL;
.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
.dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
.srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
.dependencyFlags = 0;
};
In words, they would mean (or at least that’s what I want them to mean):
- Sync whatever comes before with my firstSubpass for the most common operations (i.e. access masks.
- Sync whatever comes after with my lastSubpass for the most common operations (i.e. access masks)
The first questions would be: Are these two dependencies a good idea? What about the access masks? They would synchronize any of the stated operations, right?
What bothers me the most is a note from the specs which goes like this:
An execution dependency with only
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
in the destination stage mask will only prevent that stage from executing in subsequently submitted commands. As this stage does not perform any actual execution, this is not observable - in effect, it does not delay processing of subsequent commands. Similarly an execution dependency with onlyVK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
in the source stage mask will effectively not wait for any prior commands to complete.
What does this mean? Does this mean, that the dependencies like I have specified them, would actually NOT synchronize anything? If it doesn’t mean that, what else is meant by “in the source stage mask will effectively not wait for any prior commands to complete”?
If I really can not achieve synchronization with the two dependencies stated above, how else do they have to be configured?