From 55080bfbdedde5aedf2cf3a856e4baa9efb1bf6f Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 7 Jun 2023 10:26:31 +0300 Subject: [PATCH] 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 Reviewed-by: Ivan Briano Part-of: (cherry picked from commit 76cf391255df07e8a2f0ffcdea74707baba8587a) --- .pick_status.json | 2 +- src/vulkan/runtime/vk_command_buffer.h | 6 +++ src/vulkan/runtime/vk_render_pass.c | 59 ++++++++++++++++++++------ src/vulkan/runtime/vk_render_pass.h | 19 ++++++++- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 891729bec6e..f61f9a97e64 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/vulkan/runtime/vk_command_buffer.h b/src/vulkan/runtime/vk_command_buffer.h index 1e22b122596..8855bc4e0cc 100644 --- a/src/vulkan/runtime/vk_command_buffer.h +++ b/src/vulkan/runtime/vk_command_buffer.h @@ -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]; diff --git a/src/vulkan/runtime/vk_render_pass.c b/src/vulkan/runtime/vk_render_pass.c index bc1ae993091..7e6d41efbe6 100644 --- a/src/vulkan/runtime/vk_render_pass.c +++ b/src/vulkan/runtime/vk_render_pass.c @@ -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); diff --git a/src/vulkan/runtime/vk_render_pass.h b/src/vulkan/runtime/vk_render_pass.h index 3c028be898c..0e00c4f3aa9 100644 --- a/src/vulkan/runtime/vk_render_pass.h +++ b/src/vulkan/runtime/vk_render_pass.h @@ -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