From 27a5d846328aef744b3b8cb7ff8adf26c5539b4d Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Wed, 28 May 2025 09:57:56 -0400 Subject: [PATCH] intel/isl: Fix isl_get_sampler_clear_field_offset() Through testing, I've found that the sampler will fetch the clear color pixel from the converted clear color field in more cases. So, stop reporting the raw dword offset for them: * On gfx12.5, for 32-bpc color images. * On gfx11-12.0, for 64-bpp color images. Reviewed-by: Lionel Landwerlin Part-of: --- src/gallium/drivers/iris/iris_clear.c | 3 +- src/intel/blorp/blorp_blit.c | 5 ++-- src/intel/isl/isl.c | 43 +++++++++++++++++++-------- src/intel/isl/isl.h | 2 +- src/intel/vulkan/genX_cmd_buffer.c | 2 +- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c index 7c242cb0f91..0e2e67c457a 100644 --- a/src/gallium/drivers/iris/iris_clear.c +++ b/src/gallium/drivers/iris/iris_clear.c @@ -574,7 +574,8 @@ fast_clear_depth(struct iris_context *ice, isl_color_value_pack(&clear_value, res->surf.format, packed_depth); const uint64_t clear_pixel_offset = res->aux.clear_color_offset + - isl_get_sampler_clear_field_offset(devinfo, res->surf.format); + isl_get_sampler_clear_field_offset(devinfo, res->surf.format, + true); iris_emit_pipe_control_write(batch, "update fast clear value (Z)", PIPE_CONTROL_WRITE_IMMEDIATE, diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index cc3c59b0ead..15758c7ac42 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -2998,8 +2998,9 @@ blorp_copy(struct blorp_batch *batch, */ ASSERTED enum isl_format src_view_fmt = params.src.view.format; ASSERTED enum isl_format src_surf_fmt = params.src.surf.format; - assert(isl_get_sampler_clear_field_offset(devinfo, src_view_fmt) == - isl_get_sampler_clear_field_offset(devinfo, src_surf_fmt)); + ASSERTED bool hiz = params.src.aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT; + assert(isl_get_sampler_clear_field_offset(devinfo, src_view_fmt, hiz) == + isl_get_sampler_clear_field_offset(devinfo, src_surf_fmt, hiz)); } if (params.src.view.format != params.dst.view.format) { diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 7749a0282ae..8bd75a4dea0 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -536,28 +536,45 @@ isl_device_get_sample_counts(const struct isl_device *dev) uint64_t isl_get_sampler_clear_field_offset(const struct intel_device_info *devinfo, - enum isl_format format) + enum isl_format format, bool is_depth) { assert(devinfo->ver == 11 || devinfo->ver == 12); + const struct isl_format_layout *fmtl = isl_format_get_layout(format); - /* For 32bpc formats, the sampler fetches the raw clear color dwords - * used for rendering instead of the converted pixel dwords typically - * used for sampling. The CLEAR_COLOR struct page documents this for - * 128bpp formats, but not for 32bpp and 64bpp formats. - * - * Note that although the sampler doesn't use the converted clear color - * field with 32bpc formats, the hardware will still convert the clear - * color to a pixel when the surface format size is less than 128bpp. + /* For 128bpp formats, the only place with enough bits to store the clear + * color is the raw clear color field. */ - if (isl_format_get_layout(format)->channels.r.bits == 32) + if (fmtl->bpb == 128) return 0; - /* According to Wa_2201730850, the gfx120 sampler reads the - * U24_X8-formatted pixel from the first raw clear color dword. + /* Docs state that the converted depth value is found in the raw clear + * color dword for Red. Test results indicate that this is not actually + * true for every depth format and on every platform. An exception exists + * however for D32_FLOAT. */ - if (devinfo->verx10 == 120 && format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) + if (is_depth && format == ISL_FORMAT_R32_FLOAT) return 0; + if (devinfo->verx10 <= 120) { + /* For R32 formats, the ICL and TGL sampler fetches the raw clear color + * dword used for rendering instead of the converted pixel dword + * typically used for sampling. The CLEAR_COLOR struct page documents + * this for 128bpp formats, but not for 32bpp. + * + * Note that although the sampler doesn't use the converted clear color + * field with R32 formats, the hardware will still output the converted + * pixel into that field during a fast clear. + */ + if (fmtl->bpb == 32 && fmtl->channels.r.bits == 32) + return 0; + + /* According to Wa_2201730850, the gfx120 sampler reads the + * U24_X8-formatted pixel from the first raw clear color dword. + */ + if (format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) + return 0; + } + return 16; } diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index ca81c2bf195..789ee474ac1 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -2055,7 +2055,7 @@ isl_device_get_sample_counts(const struct isl_device *dev); */ uint64_t isl_get_sampler_clear_field_offset(const struct intel_device_info *devinfo, - enum isl_format format); + enum isl_format format, bool is_depth); /** * :returns: The isl_format_layout for the given isl_format diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 605e466a12f..0166d1ba2f4 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -496,7 +496,7 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer, const uint32_t clear_pixel_offset = clear_color_addr.offset + isl_get_sampler_clear_field_offset(cmd_buffer->device->info, - depth_format); + depth_format, true); const struct anv_address clear_pixel_addr = { .bo = clear_color_addr.bo, .offset = clear_pixel_offset,