From d1eed2239d40d1dc3c12b1293bd08c97f9cc5a4a Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 14 Jan 2026 14:28:42 +0200 Subject: [PATCH] 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 Reviewed-by: Nanley Chery Part-of: --- src/intel/vulkan/anv_private.h | 6 + src/intel/vulkan/genX_cmd_buffer.c | 200 ++++++++++++++++------------- 2 files changed, 114 insertions(+), 92 deletions(-) diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 40274d514e1..0edd7a204c1 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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; }; diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 79bffd5f215..d71571bc364 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -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); + } } }