v3dv: don't load an attachment for unaligned render area if we are not storing

If the render area is not aligned to tile boundaries it means we have partially
covered tiles in the framebuffer. In this case, we always need to load the tile
buffer from memory in order to preserve the contents outside the render area
on the tile buffer store. However, if in this scenario we know we won't be
storing the tile buffer we can skip the load safely.

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18570>
This commit is contained in:
Iago Toral Quiroga
2022-09-13 08:52:58 +02:00
committed by Marge Bot
parent 34109c8c10
commit 5e8196e756
3 changed files with 45 additions and 12 deletions
+19 -6
View File
@@ -1423,7 +1423,9 @@ bool
v3dv_cmd_buffer_check_needs_load(const struct v3dv_cmd_buffer_state *state,
VkImageAspectFlags aspect,
uint32_t first_subpass_idx,
VkAttachmentLoadOp load_op)
VkAttachmentLoadOp load_op,
uint32_t last_subpass_idx,
VkAttachmentStoreOp store_op)
{
/* We call this with image->vk.aspects & aspect, so 0 means the aspect we are
* testing does not exist in the image.
@@ -1443,9 +1445,14 @@ v3dv_cmd_buffer_check_needs_load(const struct v3dv_cmd_buffer_state *state,
if (state->job->is_subpass_continue)
return true;
/* If the area is not aligned to tile boundaries, we always need to load */
if (!state->tile_aligned_render_area)
/* If the area is not aligned to tile boundaries and we are going to store,
* then we need to load to preserve contents outside the render area.
*/
if (!state->tile_aligned_render_area &&
v3dv_cmd_buffer_check_needs_store(state, aspect, last_subpass_idx,
store_op)) {
return true;
}
/* The attachment load operations must be LOAD */
return load_op == VK_ATTACHMENT_LOAD_OP_LOAD;
@@ -1539,7 +1546,9 @@ cmd_buffer_subpass_check_double_buffer_mode(struct v3dv_cmd_buffer *cmd_buffer,
if (v3dv_cmd_buffer_check_needs_load(state,
VK_IMAGE_ASPECT_COLOR_BIT,
attachment->first_subpass,
attachment->desc.loadOp)) {
attachment->desc.loadOp,
attachment->last_subpass,
attachment->desc.storeOp)) {
return;
}
@@ -1562,14 +1571,18 @@ cmd_buffer_subpass_check_double_buffer_mode(struct v3dv_cmd_buffer *cmd_buffer,
if (v3dv_cmd_buffer_check_needs_load(state,
ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
ds_attachment->first_subpass,
ds_attachment->desc.loadOp)) {
ds_attachment->desc.loadOp,
ds_attachment->last_subpass,
ds_attachment->desc.storeOp)) {
return;
}
if (v3dv_cmd_buffer_check_needs_load(state,
ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
ds_attachment->first_subpass,
ds_attachment->desc.stencilLoadOp)) {
ds_attachment->desc.stencilLoadOp,
ds_attachment->last_subpass,
ds_attachment->desc.stencilStoreOp)) {
return;
}
+3 -1
View File
@@ -1633,7 +1633,9 @@ void v3dv_cmd_buffer_merge_barrier_state(struct v3dv_barrier_state *dst,
bool v3dv_cmd_buffer_check_needs_load(const struct v3dv_cmd_buffer_state *state,
VkImageAspectFlags aspect,
uint32_t first_subpass_idx,
VkAttachmentLoadOp load_op);
VkAttachmentLoadOp load_op,
uint32_t last_subpass_idx,
VkAttachmentStoreOp store_op);
bool v3dv_cmd_buffer_check_needs_store(const struct v3dv_cmd_buffer_state *state,
VkImageAspectFlags aspect,
+23 -5
View File
@@ -229,11 +229,17 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
attachment->first_subpass :
attachment->views[layer].first_subpass;
uint32_t last_subpass = !pass->multiview_enabled ?
attachment->last_subpass :
attachment->views[layer].last_subpass;
bool needs_load =
v3dv_cmd_buffer_check_needs_load(state,
VK_IMAGE_ASPECT_COLOR_BIT,
first_subpass,
attachment->desc.loadOp);
attachment->desc.loadOp,
last_subpass,
attachment->desc.storeOp);
if (needs_load) {
struct v3dv_image_view *iview =
state->attachments[attachment_idx].image_view;
@@ -254,17 +260,25 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
ds_attachment->first_subpass :
ds_attachment->views[layer].first_subpass;
uint32_t ds_last_subpass = !pass->multiview_enabled ?
ds_attachment->last_subpass :
ds_attachment->views[layer].last_subpass;
const bool needs_depth_load =
v3dv_cmd_buffer_check_needs_load(state,
ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
ds_first_subpass,
ds_attachment->desc.loadOp);
ds_attachment->desc.loadOp,
ds_last_subpass,
ds_attachment->desc.storeOp);
const bool needs_stencil_load =
v3dv_cmd_buffer_check_needs_load(state,
ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
ds_first_subpass,
ds_attachment->desc.stencilLoadOp);
ds_attachment->desc.stencilLoadOp,
ds_last_subpass,
ds_attachment->desc.stencilStoreOp);
if (needs_depth_load || needs_stencil_load) {
struct v3dv_image_view *iview =
@@ -834,7 +848,9 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
v3dv_cmd_buffer_check_needs_load(state,
ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
ds_attachment->first_subpass,
ds_attachment->desc.stencilLoadOp);
ds_attachment->desc.stencilLoadOp,
ds_attachment->last_subpass,
ds_attachment->desc.stencilStoreOp);
bool needs_stencil_store =
v3dv_cmd_buffer_check_needs_store(state,
@@ -1434,7 +1450,9 @@ job_update_ez_state(struct v3dv_job *job,
v3dv_cmd_buffer_check_needs_load(state,
ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
ds_attachment->first_subpass,
ds_attachment->desc.loadOp);
ds_attachment->desc.loadOp,
ds_attachment->last_subpass,
ds_attachment->desc.storeOp);
if (needs_depth_load) {
struct v3dv_framebuffer *fb = state->framebuffer;