From b5f4b16811a6f08f8210f97e69ea4db69be51c35 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Fri, 29 Mar 2024 11:24:21 -0500 Subject: [PATCH] nak: Implement load_ubo with an indirect cbuf index Part-of: --- src/nouveau/compiler/nak/encode_sm50.rs | 10 +++++++++- src/nouveau/compiler/nak/from_nir.rs | 25 ++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/nouveau/compiler/nak/encode_sm50.rs b/src/nouveau/compiler/nak/encode_sm50.rs index 959d720dc5f..274f079e53b 100644 --- a/src/nouveau/compiler/nak/encode_sm50.rs +++ b/src/nouveau/compiler/nak/encode_sm50.rs @@ -488,7 +488,15 @@ impl SM50Instr { self.set_reg_src(8..16, op.offset); self.set_field(20..36, cb.offset); self.set_field(36..41, cb_idx); - self.set_field(44..46, 0_u8); // TODO: subop + self.set_field( + 44..46, + match op.mode { + LdcMode::Indexed => 0_u8, + LdcMode::IndexedLinear => 1_u8, + LdcMode::IndexedSegmented => 2_u8, + LdcMode::IndexedSegmentedLinear => 3_u8, + }, + ); self.set_mem_type(48..51, op.mem_type); } diff --git a/src/nouveau/compiler/nak/from_nir.rs b/src/nouveau/compiler/nak/from_nir.rs index 44379deb897..e1796a8fb1e 100644 --- a/src/nouveau/compiler/nak/from_nir.rs +++ b/src/nouveau/compiler/nak/from_nir.rs @@ -2474,7 +2474,7 @@ impl<'a> ShaderFromNir<'a> { nir_intrinsic_load_ubo => { let size_B = (intrin.def.bit_size() / 8) * intrin.def.num_components(); - let idx = srcs[0]; + let idx = &srcs[0]; let (off, off_imm) = self.get_io_addr_offset(&srcs[1], 16); let (off, off_imm) = @@ -2507,8 +2507,27 @@ impl<'a> ShaderFromNir<'a> { }); } } else { - - panic!("Indirect UBO indices not yet supported"); + // In the IndexedSegmented mode, the hardware computes the + // actual index and offset as follows: + // + // idx = imm_idx + reg[31:16] + // offset = imm_offset + reg[15:0] + // ldc c[idx][offset] + // + // So pack the index and offset accordingly + let idx = self.get_src(idx); + let off_idx = b.prmt(off, idx, [0, 1, 4, 5]); + let cb = CBufRef { + buf: CBuf::Binding(0), + offset: off_imm, + }; + b.push_op(OpLdc { + dst: dst.into(), + cb: cb.into(), + offset: off_idx.into(), + mode: LdcMode::IndexedSegmented, + mem_type: MemType::from_size(size_B, false), + }); } self.set_dst(&intrin.def, dst); }