diff --git a/src/gallium/drivers/iris/iris_resolve.c b/src/gallium/drivers/iris/iris_resolve.c index bf1a8f8fef6..21772f88243 100644 --- a/src/gallium/drivers/iris/iris_resolve.c +++ b/src/gallium/drivers/iris/iris_resolve.c @@ -1163,19 +1163,13 @@ iris_resource_prepare_texture(struct iris_context *ice, clear_supported = false; } - /* On gfx11+, the sampler reads clear values stored in pixel form. The - * location the sampler reads from is dependent on the bits-per-channel of - * the format. Specifically, a pixel is read from the Raw Clear Color - * fields if the format is 32bpc. Otherwise, it's read from the Converted - * Clear Color fields. To avoid modifying the clear color, disable it if - * the new format points the sampler to an incompatible location. - * - * Note: although hardware looks at the bits-per-channel of the format, we - * only need to check the red channel's size here. In the scope of formats - * supporting fast-clears, all 32bpc formats have 32-bit red channels and - * vice-versa. + /* With indirect clear colors, the sampler reads clear values stored in + * pixel form. The location the sampler reads from is dependent on the + * bits-per-channel of the format. Disable support for clear colors if the + * new format points the sampler to an incompatible location. See + * isl_get_sampler_clear_field_offset() for more information. */ - if (devinfo->ver >= 11 && + if (res->aux.clear_color_bo && isl_format_get_layout(res->surf.format)->channels.r.bits != 32 && isl_format_get_layout(view_format)->channels.r.bits == 32) { clear_supported = false; diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index 930cadecda1..af75d1394bd 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -2973,24 +2973,14 @@ blorp_copy(struct blorp_batch *batch, if (isl_aux_usage_has_fast_clears(params.src.aux_usage) && isl_dev->ss.clear_color_state_size > 0) { - /* 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 Clear Color Conversion hardware feature - * still occurs when the format sizes are less than 128bpp. - * - * The sampler changing its clear color fetching location can be a - * problem in some cases, but we won't run into them here. When using an - * indirect clear color, we won't create 32bpc views of non-32bpc - * surfaces (and vice-versa). + /* Depending on the format, the sampler may change the location from + * which it fetches the clear color. This can be a problem in some + * cases, so make sure that the view format won't change the location. */ - const struct isl_format_layout *src_view_fmtl = - isl_format_get_layout(params.src.view.format); - assert((src_fmtl->channels.r.bits == 32) == - (src_view_fmtl->channels.r.bits == 32)); + 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)); } if (params.src.view.format != params.dst.view.format) { diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 7fea1e2ab83..089b37e4039 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -459,6 +459,33 @@ 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) +{ + assert(devinfo->ver == 11 || devinfo->ver == 12); + + /* 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. + */ + if (isl_format_get_layout(format)->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 (devinfo->verx10 == 120 && format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) + return 0; + + return 16; +} + static uint32_t isl_get_miptail_base_row(enum isl_tiling tiling) { diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index d72d7db1c0e..a64cf58b073 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -1984,6 +1984,14 @@ isl_device_init(struct isl_device *dev, isl_sample_count_mask_t ATTRIBUTE_CONST isl_device_get_sample_counts(const struct isl_device *dev); +/** + * :returns: The offset of the field within CLEAR_COLOR from which the sampler + * fetches the clear color. + */ +uint64_t +isl_get_sampler_clear_field_offset(const struct intel_device_info *devinfo, + enum isl_format format); + /** * :returns: The isl_format_layout for the given isl_format */