[Mesa-stable] [PATCH 7/8] radv: add implicit external subpass dependencies
Fredrik Höglund
fredrik at kde.org
Tue Jun 26 21:49:35 UTC 2018
Cc: <mesa-stable at lists.freedesktop.org>
Signed-off-by: Fredrik Höglund <fredrik at kde.org>
---
src/amd/vulkan/radv_pass.c | 107 +++++++++++++++++++++++++++++++---
src/amd/vulkan/radv_private.h | 8 ++-
2 files changed, 105 insertions(+), 10 deletions(-)
diff --git a/src/amd/vulkan/radv_pass.c b/src/amd/vulkan/radv_pass.c
index 17dafaca071..5bdaa7fd554 100644
--- a/src/amd/vulkan/radv_pass.c
+++ b/src/amd/vulkan/radv_pass.c
@@ -91,6 +91,8 @@ VkResult radv_CreateRenderPass(
att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
// att->store_op = pCreateInfo->pAttachments[i].storeOp;
// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
+ att->first_subpass = UINT32_MAX;
+ att->last_subpass = UINT32_MAX;
}
VkAttachmentReference *p = (void *) pass + subpass_attachments_offset;
@@ -109,10 +111,14 @@ VkResult radv_CreateRenderPass(
p += desc->inputAttachmentCount;
for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
+ uint32_t a = desc->pInputAttachments[j].attachment;
subpass->input_attachments[j]
= desc->pInputAttachments[j];
- if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
- pass->attachments[desc->pInputAttachments[j].attachment].view_mask |= subpass->view_mask;
+ if (a != VK_ATTACHMENT_UNUSED) {
+ pass->attachments[a].view_mask |= subpass->view_mask;
+ pass->attachments[a].first_subpass = MIN2(pass->attachments[a].first_subpass, i);
+ pass->attachments[a].last_subpass = i;
+ }
}
}
@@ -121,11 +127,14 @@ VkResult radv_CreateRenderPass(
p += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
+ uint32_t a = desc->pColorAttachments[j].attachment;
subpass->color_attachments[j]
= desc->pColorAttachments[j];
- if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
- pass->attachments[desc->pColorAttachments[j].attachment].view_mask |= subpass->view_mask;
- color_sample_count = pCreateInfo->pAttachments[desc->pColorAttachments[j].attachment].samples;
+ if (a != VK_ATTACHMENT_UNUSED) {
+ pass->attachments[a].view_mask |= subpass->view_mask;
+ pass->attachments[a].first_subpass = MIN2(pass->attachments[a].first_subpass, i);
+ pass->attachments[a].last_subpass = i;
+ color_sample_count = pCreateInfo->pAttachments[a].samples;
}
}
}
@@ -141,17 +150,22 @@ VkResult radv_CreateRenderPass(
= desc->pResolveAttachments[j];
if (a != VK_ATTACHMENT_UNUSED) {
subpass->has_resolve = true;
- pass->attachments[desc->pResolveAttachments[j].attachment].view_mask |= subpass->view_mask;
+ pass->attachments[a].view_mask |= subpass->view_mask;
+ pass->attachments[a].first_subpass = MIN2(pass->attachments[a].first_subpass, i);
+ pass->attachments[a].last_subpass = i;
}
}
}
if (desc->pDepthStencilAttachment) {
+ uint32_t a = desc->pDepthStencilAttachment->attachment;
subpass->depth_stencil_attachment =
*desc->pDepthStencilAttachment;
- if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
- pass->attachments[desc->pDepthStencilAttachment->attachment].view_mask |= subpass->view_mask;
- depth_sample_count = pCreateInfo->pAttachments[desc->pDepthStencilAttachment->attachment].samples;
+ if (a != VK_ATTACHMENT_UNUSED) {
+ pass->attachments[a].view_mask |= subpass->view_mask;
+ pass->attachments[a].first_subpass = MIN2(pass->attachments[a].first_subpass, i);
+ pass->attachments[a].last_subpass = i;
+ depth_sample_count = pCreateInfo->pAttachments[a].samples;
}
} else {
subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
@@ -170,15 +184,21 @@ VkResult radv_CreateRenderPass(
continue;
if (src == VK_SUBPASS_EXTERNAL) {
+ assert(dst != VK_SUBPASS_EXTERNAL && dst < pCreateInfo->subpassCount);
+ pass->subpasses[dst].explicit_dependency_from_external = true;
+
/* Add all dependencies from external to the first subpass */
dst = 0;
}
if (dst == VK_SUBPASS_EXTERNAL) {
+ assert(src != VK_SUBPASS_EXTERNAL && src < pCreateInfo->subpassCount);
+ pass->subpasses[src].explicit_dependency_to_external = true;
if (pCreateInfo->pDependencies[i].dstStageMask != VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
pass->end_barrier.src_stage_mask |= pCreateInfo->pDependencies[i].srcStageMask;
pass->end_barrier.src_access_mask |= pCreateInfo->pDependencies[i].srcAccessMask;
pass->end_barrier.dst_access_mask |= pCreateInfo->pDependencies[i].dstAccessMask;
} else {
+ assert(dst < pCreateInfo->subpassCount);
if (pCreateInfo->pDependencies[i].dstStageMask != VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
pass->subpasses[dst].start_barrier.src_stage_mask |= pCreateInfo->pDependencies[i].srcStageMask;
pass->subpasses[dst].start_barrier.src_access_mask |= pCreateInfo->pDependencies[i].srcAccessMask;
@@ -186,6 +206,75 @@ VkResult radv_CreateRenderPass(
}
}
+ /* The Vulkan specification says:
+ *
+ * "If there is no subpass dependency from VK_SUBPASS_EXTERNAL
+ * to the first subpass that uses an attachment, then an implicit
+ * subpass dependency exists from VK_SUBPASS_EXTERNAL to the first
+ * subpass it is used in. The subpass dependency operates as if
+ * defined with the following parameters:
+ *
+ * VkSubpassDependency implicitDependency = {
+ * .srcSubpass = VK_SUBPASS_EXTERNAL;
+ * .dstSubpass = firstSubpass; // First subpass attachment is used in
+ * .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ * .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+ * .srcAccessMask = 0;
+ * .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;
+ * };"
+ *
+ * Similarly, if there is no subpass dependency from the last
+ * subpass that uses an attachment to VK_SUBPASS_EXTERNAL,
+ * then an implicit subpass dependency exists from the last
+ * subpass it is used in to VK_SUBPASS_EXTERNAL. The subpass
+ * dependency operates as if defined with the following
+ * parameters:
+ *
+ * VkSubpassDependency implicitDependency = {
+ * .srcSubpass = lastSubpass; // Last subpass attachment is used in
+ * .dstSubpass = VK_SUBPASS_EXTERNAL;
+ * .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+ * .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_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 = 0;
+ * .dependencyFlags = 0;
+ * };"
+ */
+ for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+ const uint32_t first_subpass = pass->attachments[i].first_subpass;
+ const uint32_t last_subpass = pass->attachments[i].last_subpass;
+
+ /* Implicit dependency from external */
+ if (first_subpass != UINT32_MAX && !pass->subpasses[first_subpass].explicit_dependency_from_external) {
+ /* We always add the dependency to the first subpass to avoid repeating dependencies */
+ pass->subpasses[0].start_barrier.dst_access_mask |=
+ 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;
+ }
+
+ /* Implicit dependency to external */
+ if (last_subpass != UINT32_MAX && !pass->subpasses[last_subpass].explicit_dependency_to_external) {
+ pass->end_barrier.src_access_mask |=
+ 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;
+ }
+ }
+
*pRenderPass = radv_render_pass_to_handle(pass);
return VK_SUCCESS;
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 8627b3c7696..adf259981f1 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1705,7 +1705,11 @@ struct radv_subpass {
VkAttachmentReference depth_stencil_attachment;
/** Subpass has at least one resolve attachment */
- bool has_resolve;
+ bool has_resolve:1;
+
+ /** Used during renderpass creation */
+ bool explicit_dependency_from_external:1;
+ bool explicit_dependency_to_external:1;
struct radv_subpass_barrier start_barrier;
@@ -1721,6 +1725,8 @@ struct radv_render_pass_attachment {
VkImageLayout initial_layout;
VkImageLayout final_layout;
uint32_t view_mask;
+ uint32_t first_subpass;
+ uint32_t last_subpass;
};
struct radv_render_pass {
--
2.17.0
More information about the mesa-stable
mailing list