From 71becd1b44803fe28081b47c9f3ff1d2616681df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 27 Mar 2024 11:53:26 -0400 Subject: [PATCH] nir/opt_varyings: don't generate IO with unsupported bit sizes Backward inter-shader code motion turns ALU results into outputs, which led to getting IO with unsupported bit sizes. This prevents that. There is a new NIR option flag that indicates 16-bit support. Fixes: c66967b5cb7 - nir: add nir_opt_varyings, new pass optimizing and compacting varyings Reviewed-By: Mike Blumenkrantz Part-of: --- src/compiler/nir/nir.h | 2 ++ src/compiler/nir/nir_opt_varyings.c | 23 +++++++++++++++---- .../nir/tests/nir_opt_varyings_test.h | 1 + 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 293e819e1a5..b26cda974b3 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3588,6 +3588,8 @@ typedef enum { */ nir_io_dont_use_pos_for_non_fs_varyings = BITFIELD_BIT(1), + nir_io_16bit_input_output_support = BITFIELD_BIT(2), + /* Options affecting the GLSL compiler are below. */ /** diff --git a/src/compiler/nir/nir_opt_varyings.c b/src/compiler/nir/nir_opt_varyings.c index 511315d3a2d..fec59e82ee6 100644 --- a/src/compiler/nir/nir_opt_varyings.c +++ b/src/compiler/nir/nir_opt_varyings.c @@ -3382,6 +3382,23 @@ backward_inter_shader_code_motion(struct linkage_info *linkage, if (!num_movable_loads) return false; + /* Inter-shader code motion turns ALU results into outputs, but not all + * bit sizes are supported by outputs. + * + * The 1-bit type is allowed because the pass always promotes 1-bit + * outputs to 16 or 32 bits, whichever is supported. + * + * TODO: We could support replacing 2 32-bit inputs with one 64-bit + * post-dominator by supporting 64 bits here, but the likelihood of that + * occuring seems low. + */ + unsigned supported_io_types = 32 | 1; + + if (linkage->producer_builder.shader->options->io_options & + linkage->consumer_builder.shader->options->io_options & + nir_io_16bit_input_output_support) + supported_io_types |= 16; + struct nir_use_dominance_state *postdom_state = nir_calc_use_dominance_impl(linkage->consumer_builder.impl, true); @@ -3403,10 +3420,8 @@ backward_inter_shader_code_motion(struct linkage_info *linkage, /* This can only be an ALU instruction. */ nir_alu_instr *alu = nir_instr_as_alu(iter); - /* Skip 64-bit defs and keep searching. Replacing 32-bit inputs - * with one 64-bit input is unlikely to benefit. - */ - if (alu->def.bit_size == 64) + /* Skip unsupported bit sizes and keep searching. */ + if (!(alu->def.bit_size & supported_io_types)) continue; /* Skip comparison opcodes that directly source the first load diff --git a/src/compiler/nir/tests/nir_opt_varyings_test.h b/src/compiler/nir/tests/nir_opt_varyings_test.h index 1e5553fc2c0..5e65ec5004f 100644 --- a/src/compiler/nir/tests/nir_opt_varyings_test.h +++ b/src/compiler/nir/tests/nir_opt_varyings_test.h @@ -52,6 +52,7 @@ protected: memset(&options, 0, sizeof(options)); options.varying_expression_max_cost = varying_expression_max_cost; + options.io_options = nir_io_16bit_input_output_support; } virtual ~nir_opt_varyings_test()