asahi: inline UVS indices

this lets us optimize VS for linked shaders (across APIs). less indirection,
less ALU in the VS, less loads in the preamble (Vulkan) / USC uniform pushes
(OpenGL). not the most critical thing, this was already optimized to make
unlinked shaders fast, but it can't hurt ;)

also optimizing linked shaders is less objectionable from an ESO
perspective than optimizing static state.

GL:

   total instrs in shared programs: 2866067 -> 2778519 (-3.05%)
   instrs in affected programs: 1041399 -> 953851 (-8.41%)

   total threads in shared programs: 27802944 -> 27803648 (<.01%)
threads in affected programs: 1984 -> 2688 (35.48%)

   total uniforms in shared programs: 2064008 -> 2036112 (-1.35%)
uniforms in affected programs: 978997 -> 951101 (-2.85%)

Vulkan:

   Totals from 20408 (37.78% of 54019) affected shaders:
   MaxWaves: 20342464 -> 20342976 (+0.00%)
   Instrs: 7262316 -> 6958468 (-4.18%); split: -4.18%, +0.00%
   CodeSize: 53744780 -> 51480354 (-4.21%); split: -4.22%, +0.00%
   ALU: 5691626 -> 5385049 (-5.39%); split: -5.39%, +0.00%
   FSCIB: 5691626 -> 5385049 (-5.39%); split: -5.39%, +0.00%
   IC: 1210560 -> 1210512 (-0.00%)
   GPRs: 1231162 -> 1252219 (+1.71%); split: -0.58%, +2.29%
   Uniforms: 3854892 -> 3759804 (-2.47%); split: -2.47%, +0.00%
   Preamble instrs: 3390251 -> 3238677 (-4.47%); split: -4.47%, +0.00%

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36501>
This commit is contained in:
Alyssa Rosenzweig 2025-07-31 15:42:43 -04:00 committed by Marge Bot
parent 8b5c800d1f
commit 31ecf16428

View file

@ -16,6 +16,20 @@
#include "nir_intrinsics_indices.h"
#include "shader_enums.h"
static bool
inline_uvs_index(nir_builder *b, nir_intrinsic_instr *intr, void *data)
{
struct agx_varyings_vs *varyings = data;
if (intr->intrinsic != nir_intrinsic_load_uvs_index_agx)
return false;
b->cursor = nir_before_instr(&intr->instr);
unsigned slot = nir_intrinsic_io_semantics(intr).location;
nir_def_replace(&intr->def, nir_imm_intN_t(b, varyings->slots[slot], 16));
return true;
}
struct ctx {
nir_def *layer, *viewport;
nir_cursor after_layer_viewport;
@ -208,6 +222,19 @@ agx_nir_lower_uvs(nir_shader *s, struct agx_unlinked_uvs_layout *layout)
cfg.output_count_2 = offs;
}
/* If we know the interpolation qualifiers in the vertex shader, we can
* inline UVS indices to eliminate some indirection.
*/
if (s->info.known_interpolation_qualifiers) {
struct agx_varyings_vs v;
uint64_t flat = ~(s->info.linear_varyings | s->info.perspective_varyings);
agx_assign_uvs(&v, layout, flat, s->info.linear_varyings);
nir_shader_intrinsics_pass(s, inline_uvs_index, nir_metadata_control_flow,
&v);
}
return progress;
}