Module: Mesa Branch: main Commit: 21900ec8b08438afefb32d0368635c959737154f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=21900ec8b08438afefb32d0368635c959737154f
Author: Alyssa Rosenzweig <[email protected]> Date: Tue Mar 22 19:43:59 2022 -0400 pan/bi: Handle shared/scratch on Valhall There's no .seg modifier, so we have some easy lowering to do ourselves. Signed-off-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16410> --- src/panfrost/bifrost/bifrost_compile.c | 51 ++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 81335f7643b..4871162ccc0 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -936,13 +936,49 @@ bi_addr_high(nir_src *src) bi_word(bi_src_index(src), 1) : bi_zero(); } +static void +bi_handle_segment(bi_builder *b, bi_index *addr, bi_index *addr_hi, enum bi_seg seg, int16_t *offset) +{ + /* Not needed on Bifrost or for global accesses */ + if (b->shader->arch < 9 || seg == BI_SEG_NONE) + return; + + /* There is no segment modifier on Valhall. Instead, we need to + * emit the arithmetic ourselves. We do have an offset + * available, which saves an instruction for constant offsets. + */ + bool wls = (seg == BI_SEG_WLS); + assert(wls || (seg == BI_SEG_TL)); + + bi_index base = bi_fau(wls ? BIR_FAU_WLS_PTR : BIR_FAU_TLS_PTR, false); + + if (addr->type == BI_INDEX_CONSTANT) { + int value = addr->value; + + if (value == (int16_t) value) { + *offset = value; + *addr = base; + } + } else { + *addr = bi_iadd_u32(b, base, *addr, false); + bi_mov_i32_to(b, bi_word(*addr, 1), bi_imm_u32(0)); + } + + *addr_hi = bi_word(*addr, 1); +} + static void bi_emit_load(bi_builder *b, nir_intrinsic_instr *instr, enum bi_seg seg) { + int16_t offset = 0; + bi_index addr_lo = bi_src_index(&instr->src[0]); + bi_index addr_hi = bi_addr_high(&instr->src[0]); + + bi_handle_segment(b, &addr_lo, &addr_hi, seg, &offset); + bi_load_to(b, instr->num_components * nir_dest_bit_size(instr->dest), bi_dest_index(&instr->dest), - bi_src_index(&instr->src[0]), bi_addr_high(&instr->src[0]), - seg, 0); + addr_lo, addr_hi, seg, offset); } static void @@ -952,10 +988,15 @@ bi_emit_store(bi_builder *b, nir_intrinsic_instr *instr, enum bi_seg seg) assert(nir_intrinsic_write_mask(instr) == BITFIELD_MASK(instr->num_components)); + int16_t offset = 0; + bi_index addr_lo = bi_src_index(&instr->src[1]); + bi_index addr_hi = bi_addr_high(&instr->src[1]); + + bi_handle_segment(b, &addr_lo, &addr_hi, seg, &offset); + bi_store(b, instr->num_components * nir_src_bit_size(instr->src[0]), - bi_src_index(&instr->src[0]), - bi_src_index(&instr->src[1]), bi_addr_high(&instr->src[1]), - seg, 0); + bi_src_index(&instr->src[0]), + addr_lo, addr_hi, seg, offset); } /* Exchanges the staging register with memory */
