diff options
author | Samuel Pitoiset <[email protected]> | 2020-01-09 10:55:54 +0100 |
---|---|---|
committer | Samuel Pitoiset <[email protected]> | 2020-01-23 11:25:41 +0100 |
commit | e60de085473174e5a6b5a1e33e39006e62f5c786 (patch) | |
tree | 7dd87ec98f6d2f7ebfb84e74fb4692288a270cbf /src | |
parent | 0d2da2a8c08ded525f82f294c8322642fcc7c704 (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.c | 112 |
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); |