anv: batch rendering initialization commands

Instead of :

  foreach color attachment
    transition layout
    fast clear
    slow clear

do this :

  foreach color attachment
    transition layout
  foreach color attachment
    fast clear
  foreach color attachment
    slow clear

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39982>
This commit is contained in:
Lionel Landwerlin 2026-01-14 14:28:42 +02:00 committed by Marge Bot
parent 268c7f2a44
commit d1eed2239d
2 changed files with 114 additions and 92 deletions

View file

@ -4413,6 +4413,12 @@ struct anv_attachment {
const struct anv_image_view *resolve_iview;
VkImageLayout resolve_layout;
bool clear;
bool fast_clear;
union isl_color_value clear_color;
/* Clear rectangle relative to the image */
VkClearRect image_clear_rect;
bool skip_srgb_decode;
};

View file

@ -6293,6 +6293,7 @@ void genX(CmdBeginRendering)(
}
}
/* Now deal with color attachments layout transitions */
UNUSED bool render_target_change = false;
for (uint32_t i = 0; i < gfx->color_att_count; i++) {
struct anv_attachment *att = &gfx->color_att[i];
@ -6304,6 +6305,8 @@ void genX(CmdBeginRendering)(
att->iview = NULL;
att->layout = VK_IMAGE_LAYOUT_UNDEFINED;
att->aux_usage = ISL_AUX_USAGE_NONE;
att->clear = false;
att->fast_clear = false;
att->skip_srgb_decode = false;
continue;
}
@ -6328,45 +6331,51 @@ void genX(CmdBeginRendering)(
assert(gfx->samples == 0 || gfx->samples == iview->vk.image->samples);
gfx->samples |= iview->vk.image->samples;
enum isl_aux_usage aux_usage =
anv_layout_to_aux_usage(cmd_buffer->device->info,
iview->image,
iview->vk.aspects,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
vk_att->imageLayout,
cmd_buffer->queue_family->queueFlags);
render_target_change |= att->iview != iview;
att->vk_format = iview->vk.format;
att->iview = iview;
att->layout = vk_att->imageLayout;
att->aux_usage = aux_usage;
att->aux_usage = anv_layout_to_aux_usage(
cmd_buffer->device->info, iview->image,
iview->vk.aspects, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
vk_att->imageLayout, cmd_buffer->queue_family->queueFlags);
att->skip_srgb_decode = vk_att_flags_info &&
(vk_att_flags_info->flags &
VK_RENDERING_ATTACHMENT_RESOLVE_SKIP_TRANSFER_FUNCTION_BIT_KHR);
union isl_color_value fast_clear_color = { .u32 = { 0, } };
if (vk_att->resolveMode != VK_RESOLVE_MODE_NONE) {
att->resolve_mode = vk_att->resolveMode;
att->resolve_iview =
anv_image_view_from_handle(vk_att->resolveImageView);
att->resolve_layout = vk_att->resolveImageLayout;
}
att->clear = false;
att->fast_clear = false;
if (vk_att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR &&
!(gfx->rendering_flags & VK_RENDERING_RESUMING_BIT)) {
const VkClearRect clear_rect = {
att->clear = true;
att->clear_color =
vk_to_isl_color_with_format(vk_att->clearValue.color,
iview->planes[0].isl.format);
att->image_clear_rect = (VkClearRect) {
.rect = render_area,
.baseArrayLayer = iview->vk.base_array_layer,
.layerCount = layers,
};
const union isl_color_value clear_color =
vk_to_isl_color_with_format(vk_att->clearValue.color,
iview->planes[0].isl.format);
const bool fast_clear = gfx->view_mask <= 1 &&
att->fast_clear = gfx->view_mask <= 1 &&
anv_can_fast_clear_color(cmd_buffer, iview->image,
iview->vk.aspects,
iview->vk.base_mip_level,
&clear_rect, vk_att->imageLayout,
&att->image_clear_rect,
vk_att->imageLayout,
iview->planes[0].isl.format,
iview->planes[0].isl.swizzle,
clear_color);
att->clear_color);
if (vk_att->imageLayout != initial_layout) {
assert(render_area.offset.x == 0 && render_area.offset.y == 0 &&
@ -6382,7 +6391,7 @@ void genX(CmdBeginRendering)(
initial_layout, vk_att->imageLayout,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
fast_clear,
att->fast_clear,
false /* acquire_unmodified */);
}
} else {
@ -6394,76 +6403,62 @@ void genX(CmdBeginRendering)(
initial_layout, vk_att->imageLayout,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
fast_clear,
att->fast_clear,
false /* acquire_unmodified */);
}
}
if (fast_clear) {
/* We only support fast-clears on the first LOD */
assert(iview->vk.base_mip_level == 0);
fast_clear_color = clear_color;
if (iview->image->vk.samples == 1) {
anv_image_ccs_op(cmd_buffer, iview->image,
iview->planes[0].isl.format,
iview->planes[0].isl.swizzle,
iview->vk.aspects, 0,
clear_rect.baseArrayLayer,
clear_rect.layerCount,
ISL_AUX_OP_FAST_CLEAR,
&fast_clear_color,
false);
} else {
anv_image_mcs_op(cmd_buffer, iview->image,
iview->planes[0].isl.format,
iview->planes[0].isl.swizzle,
iview->vk.aspects,
clear_rect.baseArrayLayer,
clear_rect.layerCount,
ISL_AUX_OP_FAST_CLEAR,
&fast_clear_color,
false);
}
#if GFX_VER < 20
set_image_compressed_bit(cmd_buffer, iview->image,
iview->vk.aspects, 0,
clear_rect.baseArrayLayer,
clear_rect.layerCount, true);
genX(set_fast_clear_state)(cmd_buffer, iview->image,
iview->planes[0].isl.format,
iview->planes[0].isl.swizzle,
clear_color);
#endif
} else if (is_multiview) {
u_foreach_bit(view, pRenderingInfo->viewMask) {
anv_image_clear_color(cmd_buffer, iview->image,
iview->vk.aspects,
aux_usage,
iview->planes[0].isl.format,
iview->planes[0].isl.swizzle,
iview->vk.base_mip_level,
iview->vk.base_array_layer + view, 1,
render_area, clear_color);
}
} else {
anv_image_clear_color(cmd_buffer, iview->image,
iview->vk.aspects,
aux_usage,
iview->planes[0].isl.format,
iview->planes[0].isl.swizzle,
iview->vk.base_mip_level,
clear_rect.baseArrayLayer,
clear_rect.layerCount,
render_area, clear_color);
}
} else {
/* If not LOAD_OP_CLEAR, we shouldn't have a layout transition. */
assert(vk_att->imageLayout == initial_layout);
}
}
struct isl_view isl_view = iview->planes[0].isl;
/* Do fast clearing */
for (uint32_t i = 0; i < gfx->color_att_count; i++) {
struct anv_attachment *att = &gfx->color_att[i];
if (!att->fast_clear)
continue;
if (att->iview->image->vk.samples == 1) {
anv_image_ccs_op(cmd_buffer, att->iview->image,
att->iview->planes[0].isl.format,
att->iview->planes[0].isl.swizzle,
att->iview->vk.aspects, 0,
att->image_clear_rect.baseArrayLayer,
att->image_clear_rect.layerCount,
ISL_AUX_OP_FAST_CLEAR,
&att->clear_color,
false);
} else {
anv_image_mcs_op(cmd_buffer, att->iview->image,
att->iview->planes[0].isl.format,
att->iview->planes[0].isl.swizzle,
att->iview->vk.aspects,
att->image_clear_rect.baseArrayLayer,
att->image_clear_rect.layerCount,
ISL_AUX_OP_FAST_CLEAR,
&att->clear_color,
false);
}
#if GFX_VER < 20
set_image_compressed_bit(cmd_buffer, att->iview->image,
att->iview->vk.aspects, 0,
att->image_clear_rect.baseArrayLayer,
att->image_clear_rect.layerCount, true);
genX(set_fast_clear_state)(cmd_buffer, att->iview->image,
att->iview->planes[0].isl.format,
att->iview->planes[0].isl.swizzle,
att->clear_color);
#endif
}
/* Fill surfaces, load clear colors and do slow clears */
for (uint32_t i = 0; i < gfx->color_att_count; i++) {
struct anv_attachment *att = &gfx->color_att[i];
if (att->iview == NULL)
continue;
struct isl_view isl_view = att->iview->planes[0].isl;
if (pRenderingInfo->viewMask) {
assert(isl_view.array_len >= util_last_bit(pRenderingInfo->viewMask));
isl_view.array_len = util_last_bit(pRenderingInfo->viewMask);
@ -6473,31 +6468,52 @@ void genX(CmdBeginRendering)(
}
anv_image_fill_surface_state(cmd_buffer->device,
iview->image,
iview->vk.aspects,
att->iview->image,
att->iview->vk.aspects,
&isl_view,
ISL_SURF_USAGE_RENDER_TARGET_BIT,
aux_usage, &fast_clear_color,
att->aux_usage, &att->clear_color,
0, /* anv_image_view_state_flags */
&att->surface_state);
add_surface_state_relocs(cmd_buffer, &att->surface_state);
const VkRenderingAttachmentInfo *vk_att =
&pRenderingInfo->pColorAttachments[i];
if (GFX_VER < 10 &&
(vk_att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD ||
render_area.extent.width != iview->vk.extent.width ||
render_area.extent.height != iview->vk.extent.height ||
render_area.extent.width != att->iview->vk.extent.width ||
render_area.extent.height != att->iview->vk.extent.height ||
(gfx->rendering_flags & VK_RENDERING_RESUMING_BIT)) &&
iview->image->planes[0].aux_usage != ISL_AUX_USAGE_NONE &&
iview->planes[0].isl.base_level == 0) {
att->iview->image->planes[0].aux_usage != ISL_AUX_USAGE_NONE &&
att->iview->planes[0].isl.base_level == 0) {
struct anv_state surf_state = att->surface_state.state;
genX(cmd_buffer_load_clear_color)(cmd_buffer, surf_state, iview);
genX(cmd_buffer_load_clear_color)(cmd_buffer, surf_state, att->iview);
}
if (vk_att->resolveMode != VK_RESOLVE_MODE_NONE) {
att->resolve_mode = vk_att->resolveMode;
att->resolve_iview = anv_image_view_from_handle(vk_att->resolveImageView);
att->resolve_layout = vk_att->resolveImageLayout;
if (att->clear && !att->fast_clear) {
if (is_multiview) {
u_foreach_bit(view, pRenderingInfo->viewMask) {
anv_image_clear_color(cmd_buffer, att->iview->image,
att->iview->vk.aspects,
att->aux_usage,
att->iview->planes[0].isl.format,
att->iview->planes[0].isl.swizzle,
att->iview->vk.base_mip_level,
att->iview->vk.base_array_layer + view, 1,
render_area, att->clear_color);
}
} else {
anv_image_clear_color(cmd_buffer, att->iview->image,
att->iview->vk.aspects,
att->aux_usage,
att->iview->planes[0].isl.format,
att->iview->planes[0].isl.swizzle,
att->iview->vk.base_mip_level,
att->image_clear_rect.baseArrayLayer,
att->image_clear_rect.layerCount,
render_area, att->clear_color);
}
}
}