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>
This commit is contained in:

committed by
Marge Bot

parent
f92bff9198
commit
76cf391255
@@ -174,6 +174,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];
|
||||
|
@@ -1392,13 +1392,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) {
|
||||
@@ -1650,9 +1677,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
|
||||
@@ -1770,9 +1798,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
|
||||
@@ -2048,8 +2077,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);
|
||||
@@ -2227,8 +2258,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2455,8 +2488,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);
|
||||
|
@@ -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
|
||||
@@ -425,9 +428,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. */
|
||||
@@ -439,6 +442,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
|
||||
|
Reference in New Issue
Block a user