aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2020-01-09 10:55:54 +0100
committerSamuel Pitoiset <[email protected]>2020-01-23 11:25:41 +0100
commite60de085473174e5a6b5a1e33e39006e62f5c786 (patch)
tree7dd87ec98f6d2f7ebfb84e74fb4692288a270cbf /src
parent0d2da2a8c08ded525f82f294c8322642fcc7c704 (diff)
radv: handle missing implicit subpass dependencies
When a subpass doesn't declare an explicit dependency from/to VK_SUBPASS_EXTERNAL, Vulkan says there is an implicit dependency. Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3330> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3330>
Diffstat (limited to 'src')
-rw-r--r--src/amd/vulkan/radv_pass.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/amd/vulkan/radv_pass.c b/src/amd/vulkan/radv_pass.c
index 4c3cab6855f..89343d8a0d9 100644
--- a/src/amd/vulkan/radv_pass.c
+++ b/src/amd/vulkan/radv_pass.c
@@ -60,6 +60,90 @@ radv_render_pass_add_subpass_dep(struct radv_render_pass *pass,
}
static void
+radv_render_pass_add_implicit_deps(struct radv_render_pass *pass,
+ bool has_ingoing_dep, bool has_outgoing_dep)
+{
+ /* 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;
+ * };
+ */
+
+ if (!has_ingoing_dep) {
+ const VkSubpassDependency2KHR implicit_ingoing_dep = {
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .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,
+ };
+
+ radv_render_pass_add_subpass_dep(pass, &implicit_ingoing_dep);
+ }
+
+ if (!has_outgoing_dep) {
+ const VkSubpassDependency2KHR implicit_outgoing_dep = {
+ .srcSubpass = 0,
+ .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,
+ };
+
+ radv_render_pass_add_subpass_dep(pass, &implicit_outgoing_dep);
+ }
+}
+
+static void
radv_render_pass_compile(struct radv_render_pass *pass)
{
for (uint32_t i = 0; i < pass->subpass_count; i++) {
@@ -314,6 +398,9 @@ VkResult radv_CreateRenderPass(
}
}
+ bool has_ingoing_dep = false;
+ bool has_outgoing_dep = false;
+
for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
/* Convert to a Dependency2 */
struct VkSubpassDependency2 dep2 = {
@@ -326,8 +413,19 @@ VkResult radv_CreateRenderPass(
.dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags,
};
radv_render_pass_add_subpass_dep(pass, &dep2);
+
+ /* Determine if the subpass has explicit dependencies from/to
+ * VK_SUBPASS_EXTERNAL.
+ */
+ if (pCreateInfo->pDependencies[i].srcSubpass == VK_SUBPASS_EXTERNAL)
+ has_ingoing_dep = true;
+ if (pCreateInfo->pDependencies[i].dstSubpass == VK_SUBPASS_EXTERNAL)
+ has_outgoing_dep = true;
}
+ radv_render_pass_add_implicit_deps(pass,
+ has_ingoing_dep, has_outgoing_dep);
+
radv_render_pass_compile(pass);
*pRenderPass = radv_render_pass_to_handle(pass);
@@ -511,11 +609,25 @@ VkResult radv_CreateRenderPass2(
}
}
+ bool has_ingoing_dep = false;
+ bool has_outgoing_dep = false;
+
for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
radv_render_pass_add_subpass_dep(pass,
&pCreateInfo->pDependencies[i]);
+
+ /* Determine if the subpass has explicit dependencies from/to
+ * VK_SUBPASS_EXTERNAL.
+ */
+ if (pCreateInfo->pDependencies[i].srcSubpass == VK_SUBPASS_EXTERNAL)
+ has_ingoing_dep = true;
+ if (pCreateInfo->pDependencies[i].dstSubpass == VK_SUBPASS_EXTERNAL)
+ has_outgoing_dep = true;
}
+ radv_render_pass_add_implicit_deps(pass,
+ has_ingoing_dep, has_outgoing_dep);
+
radv_render_pass_compile(pass);
*pRenderPass = radv_render_pass_to_handle(pass);