Module: Mesa Branch: main Commit: fb49715a2c54d99d6cc9154c4fc9271d945b1ada URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=fb49715a2c54d99d6cc9154c4fc9271d945b1ada
Author: Alyssa Rosenzweig <[email protected]> Date: Thu Nov 24 20:40:49 2022 -0500 agx: Lower UBOs in NIR Simpler than lowering in the backend and makes the sysvals obvious in the NIR. Signed-off-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19996> --- src/asahi/compiler/agx_compile.c | 76 ++++------------------------------ src/asahi/compiler/agx_compiler.h | 1 + src/asahi/compiler/agx_nir_lower_ubo.c | 48 +++++++++++++++++++++ src/asahi/compiler/meson.build | 1 + 4 files changed, 57 insertions(+), 69 deletions(-) diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index 506a5604a08..8deae01f4b3 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -573,42 +573,6 @@ agx_emit_load_global(agx_builder *b, agx_index dest, nir_intrinsic_instr *instr) agx_emit_cached_split(b, dest, nir_dest_num_components(instr->dest)); } -static agx_instr * -agx_emit_load_ubo(agx_builder *b, agx_index dst, nir_intrinsic_instr *instr) -{ - nir_src *offset = nir_get_io_offset_src(instr); - - if (!nir_src_is_const(instr->src[0])) - unreachable("todo: indirect UBO access"); - - /* UBO blocks are specified */ - uint32_t block = nir_src_as_uint(instr->src[0]); - - /* Each UBO has a 64-bit = 4 x 16-bit address */ - unsigned num_ubos = b->shader->nir->info.num_ubos; - unsigned base_length = (num_ubos * 4); - unsigned index = block * 4; /* 16 bit units */ - - /* Lookup the base address (TODO: indirection) */ - agx_index base = agx_indexed_sysval(b->shader, - AGX_PUSH_UBO_BASES, AGX_SIZE_64, - index, base_length); - - /* Load the data */ - assert(instr->num_components <= 4); - - /* Mov around the base to handle uniform restrictions, copyprop will usually - * clean that up. - */ - agx_device_load_to(b, dst, agx_mov(b, base), agx_src_index(offset), - agx_format_for_bits(nir_dest_bit_size(instr->dest)), - BITFIELD_MASK(instr->num_components), 0, 0); - agx_wait(b, 0); - agx_emit_cached_split(b, dst, instr->num_components); - - return NULL; -} - static void agx_emit_load(agx_builder *b, agx_index dest, nir_intrinsic_instr *instr) { @@ -801,9 +765,6 @@ agx_emit_intrinsic(agx_builder *b, nir_intrinsic_instr *instr) agx_emit_local_load_pixel(b, dst, instr); return NULL; - case nir_intrinsic_load_ubo: - return agx_emit_load_ubo(b, dst, instr); - case nir_intrinsic_load_frag_coord: agx_emit_load_frag_coord(b, dst, instr); return NULL; @@ -818,6 +779,12 @@ agx_emit_intrinsic(agx_builder *b, nir_intrinsic_instr *instr) return agx_mov_to(b, dst, agx_indexed_sysval(b->shader, AGX_PUSH_TEXTURE_BASE, AGX_SIZE_64, 0, 4)); + case nir_intrinsic_load_ubo_base_agx: + return agx_mov_to(b, dst, agx_indexed_sysval(b->shader, + AGX_PUSH_UBO_BASES, AGX_SIZE_64, + nir_src_as_uint(instr->src[0]) * 4, + b->shader->nir->info.num_ubos * 4)); + case nir_intrinsic_load_vertex_id: return agx_mov_to(b, dst, agx_abs(agx_vertex_id(b))); @@ -1703,33 +1670,6 @@ agx_lower_front_face(struct nir_builder *b, return true; } -static bool -agx_lower_aligned_offsets(struct nir_builder *b, - nir_instr *instr, UNUSED void *data) -{ - if (instr->type != nir_instr_type_intrinsic) - return false; - - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - if (intr->intrinsic != nir_intrinsic_load_ubo) - return false; - - b->cursor = nir_before_instr(&intr->instr); - - unsigned bytes = nir_dest_bit_size(intr->dest) / 8; - assert(util_is_power_of_two_or_zero(bytes) && bytes != 0); - - nir_src *offset = &intr->src[1]; - - unsigned shift = util_logbase2(bytes); - - nir_ssa_def *old = nir_ssa_for_src(b, *offset, 1); - nir_ssa_def *new = nir_ishr_imm(b, old, shift); - - nir_instr_rewrite_src_ssa(instr, offset, new); - return true; -} - static void agx_optimize_nir(nir_shader *nir, unsigned *preamble_size) { @@ -1989,10 +1929,8 @@ agx_preprocess_nir(nir_shader *nir) nir_var_shader_in | nir_var_shader_out, ~agx_flat_varying_mask(nir), false); } - NIR_PASS_V(nir, nir_shader_instructions_pass, - agx_lower_aligned_offsets, - nir_metadata_block_index | nir_metadata_dominance, NULL); + NIR_PASS_V(nir, agx_nir_lower_ubo); NIR_PASS_V(nir, nir_lower_ssbo); /* Varying output is scalar, other I/O is vector */ diff --git a/src/asahi/compiler/agx_compiler.h b/src/asahi/compiler/agx_compiler.h index 45ffa20c06a..61ba7075412 100644 --- a/src/asahi/compiler/agx_compiler.h +++ b/src/asahi/compiler/agx_compiler.h @@ -809,6 +809,7 @@ bool agx_lower_resinfo(nir_shader *s); bool agx_nir_lower_array_texture(nir_shader *s); bool agx_nir_opt_preamble(nir_shader *s, unsigned *preamble_size); bool agx_nir_lower_load_mask(nir_shader *shader); +bool agx_nir_lower_ubo(nir_shader *shader); #ifdef __cplusplus } /* extern C */ diff --git a/src/asahi/compiler/agx_nir_lower_ubo.c b/src/asahi/compiler/agx_nir_lower_ubo.c new file mode 100644 index 00000000000..449abcb8848 --- /dev/null +++ b/src/asahi/compiler/agx_nir_lower_ubo.c @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Alyssa Rosenzweig + * SPDX-License-Identifier: MIT + */ + +#include <assert.h> +#include "agx_compiler.h" +#include "compiler/nir/nir_builder.h" +#include "agx_internal_formats.h" + +static bool +pass(struct nir_builder *b, nir_instr *instr, UNUSED void *data) +{ + if (instr->type != nir_instr_type_intrinsic) + return false; + + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + if (intr->intrinsic != nir_intrinsic_load_ubo) + return false; + + b->cursor = nir_before_instr(instr); + + nir_ssa_def *ubo_index = nir_ssa_for_src(b, intr->src[0], 1); + nir_ssa_def *offset = nir_ssa_for_src(b, *nir_get_io_offset_src(intr), 1); + + unsigned dest_size = nir_dest_bit_size(intr->dest); + assert((dest_size == 16 || dest_size == 32) && "other sizes lowered"); + + nir_ssa_def *value = + nir_load_constant_agx(b, intr->num_components, dest_size, + nir_load_ubo_base_agx(b, ubo_index), + nir_udiv_imm(b, offset, (dest_size / 8)), + .format = (dest_size == 32) ? + AGX_INTERNAL_FORMAT_I32 : + AGX_INTERNAL_FORMAT_I16); + + nir_ssa_def_rewrite_uses(&intr->dest.ssa, value); + return true; +} + +bool +agx_nir_lower_ubo(nir_shader *shader) +{ + return nir_shader_instructions_pass(shader, pass, + nir_metadata_block_index | + nir_metadata_dominance, + NULL); +} diff --git a/src/asahi/compiler/meson.build b/src/asahi/compiler/meson.build index 8663508a572..676bce4479e 100644 --- a/src/asahi/compiler/meson.build +++ b/src/asahi/compiler/meson.build @@ -25,6 +25,7 @@ libasahi_agx_files = files( 'agx_liveness.c', 'agx_nir_lower_texture.c', 'agx_nir_lower_load_mask.c', + 'agx_nir_lower_ubo.c', 'agx_nir_opt_preamble.c', 'agx_lower_64bit.c', 'agx_lower_resinfo.c',
