ac/nir/meta: allow compute blits with R5G6B5 & R5G5B5A1 formats on GFX9+

v2: add a workaround for incorrect hw rounding

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36578>
This commit is contained in:
Marek Olšák
2025-06-29 21:45:40 -04:00
committed by Marge Bot
parent 82a7085898
commit 9244618e5f
2 changed files with 13 additions and 3 deletions
+1
View File
@@ -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;
+12 -3
View File
@@ -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);