[Mesa-dev] [PATCH v2 4/5] anv/pass: Record required pipe flushes
Jason Ekstrand
jason at jlekstrand.net
Fri Apr 7 05:53:09 UTC 2017
---
src/intel/vulkan/anv_pass.c | 88 ++++++++++++++++++++++++++++++++++++++++++
src/intel/vulkan/anv_private.h | 2 +
2 files changed, 90 insertions(+)
diff --git a/src/intel/vulkan/anv_pass.c b/src/intel/vulkan/anv_pass.c
index 65c349a..9b43b01 100644
--- a/src/intel/vulkan/anv_pass.c
+++ b/src/intel/vulkan/anv_pass.c
@@ -45,6 +45,7 @@ VkResult anv_CreateRenderPass(
struct anv_render_pass *pass;
struct anv_subpass *subpasses;
struct anv_render_pass_attachment *attachments;
+ enum anv_pipe_bits *subpass_flushes;
struct anv_multialloc ma;
anv_multialloc_init2(&ma, &device->alloc, pAllocator,
@@ -52,6 +53,7 @@ VkResult anv_CreateRenderPass(
anv_multialloc_add(&ma, &pass, 1);
anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount);
anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount);
+ anv_multialloc_add(&ma, &subpass_flushes, pCreateInfo->subpassCount + 1);
VkAttachmentReference *subpass_attachments;
uint32_t subpass_attachment_count = 0;
@@ -75,6 +77,7 @@ VkResult anv_CreateRenderPass(
pass->attachment_count = pCreateInfo->attachmentCount;
pass->subpass_count = pCreateInfo->subpassCount;
pass->attachments = attachments;
+ pass->subpass_flushes = subpass_flushes;
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
struct anv_render_pass_attachment *att = &pass->attachments[i];
@@ -91,6 +94,7 @@ VkResult anv_CreateRenderPass(
subpass_usages += pass->subpass_count;
}
+ bool has_color = false, has_depth = false, has_input = false;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
struct anv_subpass *subpass = &pass->subpasses[i];
@@ -108,6 +112,7 @@ VkResult anv_CreateRenderPass(
uint32_t a = desc->pInputAttachments[j].attachment;
subpass->input_attachments[j] = desc->pInputAttachments[j];
if (a != VK_ATTACHMENT_UNUSED) {
+ has_input = true;
pass->attachments[a].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_INPUT;
pass->attachments[a].last_subpass_idx = i;
@@ -127,6 +132,7 @@ VkResult anv_CreateRenderPass(
uint32_t a = desc->pColorAttachments[j].attachment;
subpass->color_attachments[j] = desc->pColorAttachments[j];
if (a != VK_ATTACHMENT_UNUSED) {
+ has_color = true;
pass->attachments[a].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_DRAW;
pass->attachments[a].last_subpass_idx = i;
@@ -163,6 +169,7 @@ VkResult anv_CreateRenderPass(
*subpass_attachments++ = subpass->depth_stencil_attachment =
*desc->pDepthStencilAttachment;
if (a != VK_ATTACHMENT_UNUSED) {
+ has_depth = true;
pass->attachments[a].usage |=
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_DRAW;
@@ -174,6 +181,87 @@ VkResult anv_CreateRenderPass(
}
}
+ for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
+ const VkSubpassDependency *dep = &pCreateInfo->pDependencies[i];
+ if (dep->dstSubpass == VK_SUBPASS_EXTERNAL) {
+ pass->subpass_flushes[pass->subpass_count] |=
+ anv_pipe_invalidate_bits_for_access_flags(dep->dstAccessMask);
+ } else {
+ assert(dep->dstSubpass < pass->subpass_count);
+ pass->subpass_flushes[dep->dstSubpass] |=
+ anv_pipe_invalidate_bits_for_access_flags(dep->dstAccessMask);
+ }
+
+ if (dep->srcSubpass == VK_SUBPASS_EXTERNAL) {
+ pass->subpass_flushes[0] |=
+ anv_pipe_flush_bits_for_access_flags(dep->srcAccessMask);
+ } else {
+ assert(dep->srcSubpass < pass->subpass_count);
+ pass->subpass_flushes[dep->srcSubpass + 1] |=
+ anv_pipe_flush_bits_for_access_flags(dep->srcAccessMask);
+ }
+ }
+
+ /* From the Vulkan 1.0.39 spec:
+ *
+ * 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;
+ * };
+ *
+ * We could implement this by walking over all of the attachments and
+ * subpasses and checking to see if any of them don't have an external
+ * dependency. Or, we could just be lazy and add a couple extra flushes.
+ * We choose to be lazy.
+ */
+ if (has_input) {
+ pass->subpass_flushes[0] |=
+ ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
+ }
+ if (has_color) {
+ pass->subpass_flushes[pass->subpass_count] |=
+ ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
+ }
+ if (has_depth) {
+ pass->subpass_flushes[pass->subpass_count] |=
+ ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
+ }
+
*pRenderPass = anv_render_pass_to_handle(pass);
return VK_SUCCESS;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 6bfd3cb..512eb4b 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2150,6 +2150,8 @@ struct anv_render_pass {
uint32_t attachment_count;
uint32_t subpass_count;
VkAttachmentReference * subpass_attachments;
+ /* An array of subpass_count+1 flushes, one per subpass boundary */
+ enum anv_pipe_bits * subpass_flushes;
struct anv_render_pass_attachment * attachments;
struct anv_subpass subpasses[0];
};
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list