From d90080b51b29df14a1169d6d11a33f773add79a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 7 Jul 2024 07:50:38 -0400 Subject: [PATCH] nir/opt_vectorize_io: optionally don't vectorize IO with different types Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11443 Reviewed-by: Alyssa Rosenzweig Part-of: --- src/amd/common/ac_shader_util.c | 3 ++- src/compiler/nir/nir.h | 8 ++++++++ src/compiler/nir/nir_opt_vectorize_io.c | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/amd/common/ac_shader_util.c b/src/amd/common/ac_shader_util.c index 9a14391b8e9..fbf62e342dc 100644 --- a/src/amd/common/ac_shader_util.c +++ b/src/amd/common/ac_shader_util.c @@ -99,7 +99,8 @@ void ac_set_nir_options(struct radeon_info *info, bool use_llvm, options->io_options = nir_io_has_flexible_input_interpolation_except_flat | (info->gfx_level >= GFX8 ? nir_io_16bit_input_output_support : 0) | nir_io_prefer_scalar_fs_inputs | - nir_io_mix_convergent_flat_with_interpolated; + nir_io_mix_convergent_flat_with_interpolated | + nir_io_vectorizer_ignores_types; } bool diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 4f314aae6da..55cec80fab7 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3727,6 +3727,14 @@ typedef enum { */ nir_io_mix_convergent_flat_with_interpolated = BITFIELD_BIT(5), + /** + * Whether src_type and dest_type of IO intrinsics are irrelevant and + * should be ignored by nir_opt_vectorize_io. All drivers that always treat + * load_input and store_output as untyped and load_interpolated_input as + * float##bit_size should set this. + */ + nir_io_vectorizer_ignores_types = BITFIELD_BIT(6), + /* Options affecting the GLSL compiler are below. */ /** diff --git a/src/compiler/nir/nir_opt_vectorize_io.c b/src/compiler/nir/nir_opt_vectorize_io.c index f85857deeba..78587215668 100644 --- a/src/compiler/nir/nir_opt_vectorize_io.c +++ b/src/compiler/nir/nir_opt_vectorize_io.c @@ -76,6 +76,25 @@ compare_is_not_vectorizable(nir_intrinsic_instr *a, nir_intrinsic_instr *b) sem0.high_16bits != sem1.high_16bits) return sem0.high_16bits > sem1.high_16bits ? 1 : -1; + nir_shader *shader = + nir_cf_node_get_function(&a->instr.block->cf_node)->function->shader; + + /* Compare the types. */ + if (!(shader->options->io_options & nir_io_vectorizer_ignores_types)) { + unsigned type_a, type_b; + + if (nir_intrinsic_has_src_type(a)) { + type_a = nir_intrinsic_src_type(a); + type_b = nir_intrinsic_src_type(b); + } else { + type_a = nir_intrinsic_dest_type(a); + type_b = nir_intrinsic_dest_type(b); + } + + if (type_a != type_b) + return type_a > type_b ? 1 : -1; + } + return 0; }