From 9244618e5f260583da2c51a54330a45badb540a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 29 Jun 2025 21:45:40 -0400 Subject: [PATCH] ac/nir/meta: allow compute blits with R5G6B5 & R5G5B5A1 formats on GFX9+ v2: add a workaround for incorrect hw rounding Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/common/nir/ac_nir_meta.h | 1 + src/amd/common/nir/ac_nir_meta_cs_blit.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/amd/common/nir/ac_nir_meta.h b/src/amd/common/nir/ac_nir_meta.h index dd3edad902f..0b1aa55d56c 100644 --- a/src/amd/common/nir/ac_nir_meta.h +++ b/src/amd/common/nir/ac_nir_meta.h @@ -62,6 +62,7 @@ union ac_cs_blit_key { bool dst_is_msaa:1; bool src_has_z:1; bool dst_has_z:1; + bool dst_is_rgb5:1; bool a16:1; bool d16:1; uint8_t log_samples:2; diff --git a/src/amd/common/nir/ac_nir_meta_cs_blit.c b/src/amd/common/nir/ac_nir_meta_cs_blit.c index 174ebde9504..a8d26a29bb1 100644 --- a/src/amd/common/nir/ac_nir_meta_cs_blit.c +++ b/src/amd/common/nir/ac_nir_meta_cs_blit.c @@ -86,6 +86,12 @@ apply_blit_output_modifiers(nir_builder *b, nir_def *color, /* Discard channels not present in dst. The hardware fills unstored channels with 0. */ if (key->last_dst_channel < key->last_src_channel) color = nir_trim_vector(b, color, key->last_dst_channel + 1); + + /* Precision issue workaround for piglit/texsubimage array pbo. + * Determined by trial and error. + */ + if (key->dst_is_rgb5) + color = nir_fadd(b, color, nir_imm_floatN_t(b, -1.0/4096, bit_size)); } /* Discard channels not present in dst. The hardware fills unstored channels with 0. */ @@ -568,8 +574,8 @@ ac_prepare_compute_blit(const struct ac_cs_blit_options *options, return true; if (blit->dst.format == PIPE_FORMAT_A8R8_UNORM || /* This format fails AMD_TEST=imagecopy. */ - max_dst_chan_size == 5 || /* PIPE_FORMAT_R5G5B5A1_UNORM has precision issues */ - max_dst_chan_size == 6 || /* PIPE_FORMAT_R5G6B5_UNORM has precision issues */ + (info->gfx_level <= GFX8 && max_dst_chan_size == 5) || /* image stores with R5G5B5A1_UNORM have precision issues */ + (info->gfx_level <= GFX8 && max_dst_chan_size == 6) || /* image stores with R5G6B5_UNORM have precision issues */ util_format_is_depth_or_stencil(blit->dst.format) || dst_samples > SI_MAX_COMPUTE_BLIT_SAMPLES || /* Image stores support DCC since GFX10. Fail only for gfx queues because compute queues @@ -1108,10 +1114,13 @@ ac_prepare_compute_blit(const struct ac_cs_blit_options *options, key.dst_is_1d = blit->dst.dim == 1; key.dst_is_msaa = dst_samples > 1; key.dst_has_z = blit->dst.dim == 3 || blit->dst.is_array; + key.dst_is_rgb5 = max_dst_chan_size <= 6 && + !util_format_is_pure_integer(blit->dst.format); key.last_dst_channel = util_format_get_last_component(blit->dst.format); /* ACO doesn't support D16 on GFX8 */ - bool has_d16 = info->gfx_level >= (key.use_aco || options->use_aco ? GFX9 : GFX8); + bool has_d16 = info->gfx_level >= (key.use_aco || options->use_aco ? GFX9 : GFX8) && + !key.dst_is_rgb5; if (is_clear) { assert(dst_samples <= 8);