pan/bi: Implement load_push_constant

Bifrost supports "fast access uniforms" loaded from a single contiguous buffer.
This maps directly to Vulkan push constants, with some caveats:

* No indirect access. Indirects need to be lowered to a UBO pull.
* Strict alignment requirements. These will be met in practice.

Implement the NIR intrinsic and map it to the native hardware construct.

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16916>
This commit is contained in:
Alyssa Rosenzweig 2022-06-07 15:13:11 -04:00 committed by Marge Bot
parent 3c5f1595b8
commit 17ea1642e2
1 changed files with 30 additions and 0 deletions

View File

@ -1099,6 +1099,32 @@ bi_emit_load_ubo(bi_builder *b, nir_intrinsic_instr *instr)
kernel_input ? bi_zero() : bi_src_index(&instr->src[0]));
}
static void
bi_emit_load_push_constant(bi_builder *b, nir_intrinsic_instr *instr)
{
assert(b->shader->inputs->no_ubo_to_push && "can't mix push constant forms");
nir_src *offset = &instr->src[0];
assert(nir_src_is_const(*offset) && "no indirect push constants");
uint32_t base = nir_intrinsic_base(instr) + nir_src_as_uint(*offset);
assert((base & 3) == 0 && "unaligned push constants");
unsigned bits = nir_dest_bit_size(instr->dest) *
nir_dest_num_components(instr->dest);
unsigned n = DIV_ROUND_UP(bits, 32);
assert(n <= 4);
bi_index channels[4] = { bi_null() };
for (unsigned i = 0; i < n; ++i) {
unsigned word = (base >> 2) + i;
channels[i] = bi_fau(BIR_FAU_UNIFORM | (word >> 1), word & 1);
}
bi_emit_collect_to(b, bi_dest_index(&instr->dest), channels, n);
}
static bi_index
bi_addr_high(bi_builder *b, nir_src *src)
{
@ -1590,6 +1616,10 @@ bi_emit_intrinsic(bi_builder *b, nir_intrinsic_instr *instr)
bi_emit_load_ubo(b, instr);
break;
case nir_intrinsic_load_push_constant:
bi_emit_load_push_constant(b, instr);
break;
case nir_intrinsic_load_global:
case nir_intrinsic_load_global_constant:
bi_emit_load(b, instr, BI_SEG_NONE);