From c3fc214a980b6c0ba0d4aa4d7278f6a434c553ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 25 Mar 2024 18:05:05 -0400 Subject: [PATCH] radeonsi: implement user_data_amd for 5, 6, and 7 components correctly NIR can't handle those component counts, so we have to split it into 2 SGPR vectors where each has max 4 components. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/drivers/radeonsi/si_nir_lower_abi.c | 13 ++++++++++--- src/gallium/drivers/radeonsi/si_shader.c | 7 ++++++- src/gallium/drivers/radeonsi/si_shader_internal.h | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c index c6f6e3f469924..01238a1ca2539 100644 --- a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c +++ b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c @@ -744,10 +744,17 @@ static bool lower_intrinsic(nir_builder *b, nir_instr *instr, struct lower_abi_s s->gsvs_ring[stream_id] : nir_undef(b, 4, 32); break; } - case nir_intrinsic_load_user_data_amd: - replacement = ac_nir_load_arg(b, &args->ac, args->cs_user_data); - replacement = nir_pad_vector(b, replacement, 8); + case nir_intrinsic_load_user_data_amd: { + nir_def *low_vec4 = ac_nir_load_arg(b, &args->ac, args->cs_user_data[0]); + replacement = nir_pad_vector(b, low_vec4, 8); + + if (args->cs_user_data[1].used && intrin->def.num_components > 4) { + nir_def *high_vec4 = ac_nir_load_arg(b, &args->ac, args->cs_user_data[1]); + for (unsigned i = 0; i < high_vec4->num_components; i++) + replacement = nir_vector_insert_imm(b, replacement, nir_channel(b, high_vec4, i), 4 + i); + } break; + } default: return false; } diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index b4d8acef8b06e..4c96a07c66afb 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -677,7 +677,12 @@ void si_init_shader_args(struct si_shader *shader, struct si_shader_args *args) unsigned cs_user_data_dwords = shader->selector->info.base.cs.user_data_components_amd; if (cs_user_data_dwords) { - ac_add_arg(&args->ac, AC_ARG_SGPR, cs_user_data_dwords, AC_ARG_INT, &args->cs_user_data); + ac_add_arg(&args->ac, AC_ARG_SGPR, MIN2(cs_user_data_dwords, 4), AC_ARG_INT, + &args->cs_user_data[0]); + if (cs_user_data_dwords > 4) { + ac_add_arg(&args->ac, AC_ARG_SGPR, cs_user_data_dwords - 4, AC_ARG_INT, + &args->cs_user_data[1]); + } } /* Some descriptors can be in user SGPRs. */ diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 8e989fe862b25..30df2885cba92 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -75,7 +75,7 @@ struct si_shader_args { struct ac_arg color_start; /* CS */ struct ac_arg block_size; - struct ac_arg cs_user_data; + struct ac_arg cs_user_data[2]; struct ac_arg cs_shaderbuf[3]; struct ac_arg cs_image[3]; };