anv: Prepare for format width changes in blorp_copy()

blorp_copy() will soon gain the ability to increase the format bpb.
Prepare anv by replicating the clear color pixel on gfx12.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39974>
This commit is contained in:
Nanley Chery 2026-02-09 15:57:28 -05:00 committed by Marge Bot
parent d993e0dc47
commit 465c186fc5
4 changed files with 29 additions and 11 deletions

View file

@ -311,9 +311,9 @@ get_blorp_surf_for_anv_image(const struct anv_cmd_buffer *cmd_buffer,
}
const bool is_dest = usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT;
const bool is_depth = aspect & VK_IMAGE_ASPECT_DEPTH_BIT;
isl_surf_usage_flags_t isl_usage =
get_usage_flag_for_cmd_buffer(cmd_buffer, is_dest,
aspect & VK_IMAGE_ASPECT_DEPTH_BIT,
get_usage_flag_for_cmd_buffer(cmd_buffer, is_dest, is_depth,
anv_image_is_protected(image));
const struct anv_surface *surface = &image->planes[plane].primary_surface;
const struct anv_address address =
@ -344,11 +344,20 @@ get_blorp_surf_for_anv_image(const struct anv_cmd_buffer *cmd_buffer,
};
}
enum isl_format fmt_override = view_fmt;
if (cross_aspect && !is_depth) {
fmt_override = ISL_FORMAT_RAW;
} else if (!is_dest && device->info->ver == 12 &&
!anv_image_view_formats_incomplete(image) &&
isl_aux_usage_has_ccs_e(aux_usage)) {
fmt_override = ISL_FORMAT_RAW;
}
const struct anv_address clear_color_addr =
anv_image_get_clear_color_addr(
device, image, cross_aspect ? ISL_FORMAT_RAW : view_fmt, aspect,
!is_dest);
device, image, fmt_override, aspect, !is_dest);
blorp_surf->clear_color_addr = anv_to_blorp_address(clear_color_addr);
blorp_surf->has_replicated_pixel = fmt_override == ISL_FORMAT_RAW;
if (aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {
blorp_surf->clear_color =

View file

@ -1959,7 +1959,8 @@ anv_image_init(struct anv_device *device, struct anv_image *image,
blorp_copy_get_color_format(&device->isl_dev, image_format);
add_image_view_format(image, blorp_copy_format);
if (vk_format_is_color_depth_stencil_capable(image->vk.format))
if ((device->info->ver == 12 && image->vk.samples == 1) ||
vk_format_is_color_depth_stencil_capable(image->vk.format))
add_image_view_format(image, ISL_FORMAT_RAW);
} else {
/* We don't have a blorp_copy format query for depth-stencil formats. */

View file

@ -5991,6 +5991,8 @@ anv_image_get_clear_color_addr(UNUSED const struct anv_device *device,
}
}
/* Don't fail silently for the special raw format. */
assert(view_format != ISL_FORMAT_RAW);
assert(anv_image_view_formats_incomplete(image));
return anv_address_add(base_addr, access_offset);
}

View file

@ -933,13 +933,19 @@ set_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
const VkImageAspectFlags aspect,
const uint32_t *pixel)
{
uint8_t replicated_pixel[16];
int pixel_size_B = vk_format_get_blocksize(image->vk.format);
for (int p = 0; p < 16 / pixel_size_B; p++)
memcpy(&replicated_pixel[p * pixel_size_B], pixel, pixel_size_B);
for (int i = 0; i < image->num_view_formats; i++) {
union isl_color_value clear_color;
if (image->view_formats[i] == ISL_FORMAT_RAW) {
/* Only used for cross aspect copies (color <-> depth/stencil) */
assert(vk_format_is_color_depth_stencil_capable(image->vk.format));
assert(vk_format_get_blocksizebits(image->vk.format) <= 32);
memcpy(clear_color.u32, pixel, sizeof(clear_color.u32));
/* Used for cross aspect copies (color <-> depth/stencil) on all
* platforms and for blorp_copy() sources on gfx12 (see
* blorp_surf::has_replicated_pixel).
*/
memcpy(clear_color.u32, replicated_pixel, sizeof(clear_color.u32));
} else {
isl_color_value_unpack(&clear_color, image->view_formats[i], pixel);
}
@ -966,8 +972,8 @@ set_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
dw[6] = clear_color.u32[3];
dw[7] = 0;
dw[8] = 0;
dw[3 + sampler_offset / 4] = pixel[0];
dw[4 + sampler_offset / 4] = pixel[1];
dw[3 + sampler_offset / 4] = ((uint32_t *)replicated_pixel)[0];
dw[4 + sampler_offset / 4] = ((uint32_t *)replicated_pixel)[1];
#else
assert(cmd_buffer->device->isl_dev.ss.clear_color_state_size == 0);
assert(cmd_buffer->device->isl_dev.ss.clear_value_size == 16);