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@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@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>
This commit is contained in:
Samuel Pitoiset 2020-01-09 10:55:54 +01:00
parent 0d2da2a8c0
commit e60de08547
1 changed files with 112 additions and 0 deletions

View File

@ -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);