vulkan/runtime: add helper to query attachment layout

The runtime is turning GENERAL layouts into FEEDBACK_LOOP ones when it
detects feedback loops in a render pass. This is breaking drivers that
would like to use a different HW layout for those 2 layouts because if
the application inserts barrier in the render pass, the barriers the
driver sees are inconsistent.

This could lead to barrier of this type :
   - GENERAL       -> FEEDBACK_LOOP (runtime)
   - GENERAL       -> GENERAL       (app)
   - FEEDBACK_LOOP -> GENERAL       (runtime)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23523>
(cherry picked from commit 76cf391255)
This commit is contained in:
Lionel Landwerlin
2023-06-07 10:26:31 +03:00
committed by Eric Engestrom
parent 41f8ef617c
commit 55080bfbde
4 changed files with 71 additions and 15 deletions

View File

@@ -7744,7 +7744,7 @@
"description": "vulkan/runtime: add helper to query attachment layout",
"nominated": false,
"nomination_type": 3,
"resolution": 4,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View File

@@ -169,6 +169,12 @@ struct vk_command_buffer {
struct vk_framebuffer *framebuffer;
VkRect2D render_area;
/**
* True if we are currently inside a CmdPipelineBarrier() is inserted by
* the runtime's vk_render_pass.c
*/
bool runtime_rp_barrier;
/* This uses the same trick as STACK_ARRAY */
struct vk_attachment_state *attachments;
struct vk_attachment_state _attachments[8];

View File

@@ -1396,13 +1396,40 @@ can_use_attachment_initial_layout(struct vk_command_buffer *cmd_buffer,
return true;
}
static void
set_attachment_layout(struct vk_command_buffer *cmd_buffer,
uint32_t att_idx,
uint32_t view_mask,
VkImageLayout layout,
VkImageLayout stencil_layout)
uint32_t
vk_command_buffer_get_attachment_layout(const struct vk_command_buffer *cmd_buffer,
const struct vk_image *image,
VkImageLayout *out_layout,
VkImageLayout *out_stencil_layout)
{
const struct vk_render_pass *render_pass = cmd_buffer->render_pass;
assert(render_pass != NULL);
const struct vk_subpass *subpass =
&render_pass->subpasses[cmd_buffer->subpass_idx];
int first_view = ffs(subpass->view_mask) - 1;
for (uint32_t a = 0; a < render_pass->attachment_count; a++) {
if (cmd_buffer->attachments[a].image_view->image == image) {
*out_layout = cmd_buffer->attachments[a].views[first_view].layout;
*out_stencil_layout =
cmd_buffer->attachments[a].views[first_view].stencil_layout;
return a;
}
}
unreachable("Image not found in attachments");
}
void
vk_command_buffer_set_attachment_layout(struct vk_command_buffer *cmd_buffer,
uint32_t att_idx,
VkImageLayout layout,
VkImageLayout stencil_layout)
{
const struct vk_render_pass *render_pass = cmd_buffer->render_pass;
const struct vk_subpass *subpass =
&render_pass->subpasses[cmd_buffer->subpass_idx];
uint32_t view_mask = subpass->view_mask;
struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx];
u_foreach_bit(view, view_mask) {
@@ -1654,9 +1681,10 @@ begin_subpass(struct vk_command_buffer *cmd_buffer,
};
__vk_append_struct(color_attachment, color_initial_layout);
set_attachment_layout(cmd_buffer, sp_att->attachment,
subpass->view_mask,
sp_att->layout, VK_IMAGE_LAYOUT_UNDEFINED);
vk_command_buffer_set_attachment_layout(cmd_buffer,
sp_att->attachment,
sp_att->layout,
VK_IMAGE_LAYOUT_UNDEFINED);
}
} else {
/* We've seen at least one of the views of this attachment before so
@@ -1774,9 +1802,10 @@ begin_subpass(struct vk_command_buffer *cmd_buffer,
&stencil_initial_layout);
}
set_attachment_layout(cmd_buffer, sp_att->attachment,
subpass->view_mask,
sp_att->layout, sp_att->stencil_layout);
vk_command_buffer_set_attachment_layout(cmd_buffer,
sp_att->attachment,
sp_att->layout,
sp_att->stencil_layout);
}
} else {
/* We've seen at least one of the views of this attachment before so
@@ -2052,8 +2081,10 @@ begin_subpass(struct vk_command_buffer *cmd_buffer,
.pImageMemoryBarriers = image_barrier_count > 0 ?
image_barriers : NULL,
};
cmd_buffer->runtime_rp_barrier = true;
disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer),
&dependency_info);
cmd_buffer->runtime_rp_barrier = false;
}
STACK_ARRAY_FINISH(image_barriers);
@@ -2231,8 +2262,10 @@ end_subpass(struct vk_command_buffer *cmd_buffer,
.memoryBarrierCount = 1,
.pMemoryBarriers = &mem_barrier,
};
cmd_buffer->runtime_rp_barrier = true;
disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer),
&dependency_info);
cmd_buffer->runtime_rp_barrier = false;
}
}
@@ -2459,8 +2492,10 @@ vk_common_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
.imageMemoryBarrierCount = image_barrier_count,
.pImageMemoryBarriers = image_barriers,
};
cmd_buffer->runtime_rp_barrier = true;
disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer),
&dependency_info);
cmd_buffer->runtime_rp_barrier = false;
}
STACK_ARRAY_FINISH(image_barriers);

View File

@@ -29,6 +29,9 @@
extern "C" {
#endif
struct vk_command_buffer;
struct vk_image;
/**
* Pseudo-extension struct that may be chained into VkRenderingAttachmentInfo
* to indicate an initial layout for the attachment. This is only allowed if
@@ -420,9 +423,9 @@ vk_subpass_dependency_is_fb_local(const VkSubpassDependency2 *dep,
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
const VkPipelineStageFlags2 src_framebuffer_space_stages =
const VkPipelineStageFlags2 src_framebuffer_space_stages =
framebuffer_space_stages | VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
const VkPipelineStageFlags2 dst_framebuffer_space_stages =
const VkPipelineStageFlags2 dst_framebuffer_space_stages =
framebuffer_space_stages | VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
/* Check for frambuffer-space dependency. */
@@ -434,6 +437,18 @@ vk_subpass_dependency_is_fb_local(const VkSubpassDependency2 *dep,
return dep->dependencyFlags & VK_DEPENDENCY_BY_REGION_BIT;
}
uint32_t
vk_command_buffer_get_attachment_layout(const struct vk_command_buffer *cmd_buffer,
const struct vk_image *image,
VkImageLayout *out_layout,
VkImageLayout *out_stencil_layout);
void
vk_command_buffer_set_attachment_layout(struct vk_command_buffer *cmd_buffer,
uint32_t att_idx,
VkImageLayout layout,
VkImageLayout stencil_layout);
#ifdef __cplusplus
}
#endif