From 6a1c8d3a0cf8d2968b4ba143d012fb1eff5298d1 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Thu, 8 Jan 2026 13:34:01 -0500 Subject: [PATCH] ir3, freedreno, turnip: Lower io earlier On the gallium side, set the NIR option to leave IO lowered after linking when using GLSL. On the turnip side, move up nir_lower_io to as early as currently possible. Further turnip passes will have to be converted to intrinsics before we can switch to using the new linker. Part-of: --- src/freedreno/ir3/ir3_compiler.c | 2 ++ src/freedreno/ir3/ir3_nir.c | 29 ++++++++++++++++++- src/freedreno/vulkan/tu_shader.cc | 4 +-- .../drivers/freedreno/ir3/ir3_gallium.c | 6 ++-- .../drivers/zink/ci/zink-tu-a750-fails.txt | 7 +++-- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/freedreno/ir3/ir3_compiler.c b/src/freedreno/ir3/ir3_compiler.c index a51b65a82f1..6e0e6e60862 100644 --- a/src/freedreno/ir3/ir3_compiler.c +++ b/src/freedreno/ir3/ir3_compiler.c @@ -137,6 +137,8 @@ static const nir_shader_compiler_options ir3_base_options = { .per_view_unique_driver_locations = true, .compact_view_index = true, + + .io_options = nir_io_has_intrinsics, }; struct ir3_compiler * diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index b7054025e68..01af44c6059 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -659,9 +659,36 @@ ir3_finalize_nir(struct ir3_compiler *compiler, mesa_logi("----------------------"); } - if (s->info.stage == MESA_SHADER_GEOMETRY) + /* For vertex inputs, we expect them to all be at the top. FS inputs are also + * more optimal at the top. + */ + if (s->info.stage == MESA_SHADER_VERTEX || + s->info.stage == MESA_SHADER_FRAGMENT) + NIR_PASS(_, s, nir_opt_move_to_top, nir_move_to_top_input_loads); + + if (s->info.stage == MESA_SHADER_GEOMETRY) { + /* nir_unlower_io_to_vars expects constant indirect offsets to be folded + * in. + */ + NIR_PASS(_, s, nir_opt_constant_folding); + NIR_PASS(_, s, nir_opt_dce); + + /* GS lowering works most easily with variables, so temporarily switch + * inputs/outputs to variables and then switch back after the lowering is + * done. + */ + NIR_PASS(_, s, nir_unlower_io_to_vars, false); + /* nir_lower_io doesn't work with compact variables and non-constant + * indices, so clean up output of unlower_io_to_vars. + */ + NIR_PASS(_, s, nir_opt_constant_folding); + NIR_PASS(_, s, nir_opt_dce); + NIR_PASS(_, s, ir3_nir_lower_gs); + ir3_nir_lower_io(s); + } + NIR_PASS(_, s, nir_lower_frexp); NIR_PASS(_, s, nir_lower_amul, ir3_glsl_type_size); diff --git a/src/freedreno/vulkan/tu_shader.cc b/src/freedreno/vulkan/tu_shader.cc index 548c5e10857..af40ab313a4 100644 --- a/src/freedreno/vulkan/tu_shader.cc +++ b/src/freedreno/vulkan/tu_shader.cc @@ -2949,6 +2949,8 @@ tu_shader_create(struct tu_device *dev, NIR_PASS(_, nir, nir_lower_mem_access_bit_sizes, &options); } + ir3_nir_lower_io(nir); + struct ir3_const_allocations const_allocs = {}; NIR_PASS(_, nir, tu_lower_io, dev, shader, layout, key->read_only_input_attachments, key->dynamic_renderpass, @@ -2961,8 +2963,6 @@ tu_shader_create(struct tu_device *dev, ir3_finalize_nir(dev->compiler, &nir_options, nir); - ir3_nir_lower_io(nir); - /* This has to happen after finalizing, so that we know the final bitsize * after vectorizing. */ diff --git a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c index ae68b239d60..1516634caf9 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c @@ -461,9 +461,11 @@ ir3_screen_finalize_nir(struct pipe_screen *pscreen, struct nir_shader *nir, MESA_TRACE_FUNC(); - ir3_nir_lower_io_vars_to_temporaries(nir); + if (!nir->info.io_lowered) { + ir3_nir_lower_io_vars_to_temporaries(nir); + ir3_nir_lower_io(nir); + } ir3_finalize_nir(screen->compiler, &options, nir); - ir3_nir_lower_io(nir); } static void diff --git a/src/gallium/drivers/zink/ci/zink-tu-a750-fails.txt b/src/gallium/drivers/zink/ci/zink-tu-a750-fails.txt index 4634cbd389d..698cb5b413a 100644 --- a/src/gallium/drivers/zink/ci/zink-tu-a750-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-tu-a750-fails.txt @@ -168,9 +168,10 @@ spec@ext_framebuffer_multisample@interpolation 4 non-centroid-deriv-disabled,Fai spec@ext_framebuffer_multisample@interpolation 4 non-centroid-disabled,Fail spec@ext_framebuffer_multisample@sample-alpha-to-coverage 2 color,Fail spec@ext_framebuffer_multisample@sample-alpha-to-coverage 4 color,Fail -spec@ext_transform_feedback@max-varyings,Fail -spec@ext_transform_feedback@max-varyings@max-varying-arrays-of-arrays,Fail -spec@ext_transform_feedback@max-varyings@max-varying-single-dimension-array,Fail + +# see https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37602#note_3294118 +spec@ext_transform_feedback@max-varyings,Crash + spec@ext_transform_feedback@tessellation quad_strip wireframe,Fail spec@ext_transform_feedback@tessellation quads wireframe,Fail spec@ext_transform_feedback@tessellation triangle_fan flat_first,Fail