Mesa (master): radv: handle missing implicit subpass dependencies

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 23 10:45:38 UTC 2020


Module: Mesa
Branch: master
Commit: e60de085473174e5a6b5a1e33e39006e62f5c786
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e60de085473174e5a6b5a1e33e39006e62f5c786

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Thu Jan  9 10:55:54 2020 +0100

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 <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3330>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3330>

---

 src/amd/vulkan/radv_pass.c | 112 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

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
@@ -59,6 +59,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)
 {
@@ -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);



More information about the mesa-commit mailing list