diff --git a/src/nouveau/compiler/nak_encode_sm75.rs b/src/nouveau/compiler/nak_encode_sm75.rs index e0370ad3ffd..74b1c0347d8 100644 --- a/src/nouveau/compiler/nak_encode_sm75.rs +++ b/src/nouveau/compiler/nak_encode_sm75.rs @@ -1136,6 +1136,19 @@ impl SM75Instr { } } + fn encode_ldc(&mut self, op: &OpLdc) { + self.encode_alu( + 0x182, + Some(op.dst), + ALUSrc::from_src(&op.offset), + ALUSrc::from_src(&op.cb), + ALUSrc::None, + ); + + self.set_mem_type(73..76, op.mem_type); + self.set_field(78..80, 0_u8); /* subop */ + } + fn encode_stg(&mut self, op: &OpSt) { self.set_opcode(0x385); @@ -1493,6 +1506,7 @@ impl SM75Instr { Op::SuSt(op) => si.encode_sust(&op), Op::SuAtom(op) => si.encode_suatom(&op), Op::Ld(op) => si.encode_ld(&op), + Op::Ldc(op) => si.encode_ldc(&op), Op::St(op) => si.encode_st(&op), Op::Atom(op) => si.encode_atom(&op), Op::AtomCas(op) => si.encode_atom_cas(&op), diff --git a/src/nouveau/compiler/nak_from_nir.rs b/src/nouveau/compiler/nak_from_nir.rs index abe54ba368b..09fde3157f3 100644 --- a/src/nouveau/compiler/nak_from_nir.rs +++ b/src/nouveau/compiler/nak_from_nir.rs @@ -1094,6 +1094,8 @@ impl<'a> ShaderFromNir<'a> { self.instrs.push(Instr::new_s2r(dst, idx)); } nir_intrinsic_load_ubo => { + let size_B = + (intrin.def.bit_size() / 8) * intrin.def.num_components(); let idx = srcs[0]; let (off, off_imm) = self.get_io_addr_offset(&srcs[1], 16); let dst = self.get_dst(&intrin.def); @@ -1111,7 +1113,15 @@ impl<'a> ShaderFromNir<'a> { } self.instrs.push(pcopy.into()); } else { - panic!("Indirect UBO offsets not yet supported"); + self.instrs.push( + OpLdc { + dst: dst, + cb: cb.into(), + offset: off, + mem_type: MemType::from_size(size_B, false), + } + .into(), + ); } } else { panic!("Indirect UBO indices not yet supported"); diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs index ec2fbb7950a..af676dc160d 100644 --- a/src/nouveau/compiler/nak_ir.rs +++ b/src/nouveau/compiler/nak_ir.rs @@ -2453,6 +2453,37 @@ impl fmt::Display for OpLd { } } +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpLdc { + pub dst: Dst, + + #[src_type(ALU)] + pub cb: Src, + + #[src_type(GPR)] + pub offset: Src, + + pub mem_type: MemType, +} + +impl fmt::Display for OpLdc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let SrcRef::CBuf(cb) = self.cb.src_ref else { + panic!("Not a cbuf"); + }; + write!(f, "LDC.{} {} {}[", self.mem_type, self.dst, cb.buf)?; + if self.offset.is_zero() { + write!(f, "+{:#x}", cb.offset)?; + } else if cb.offset == 0 { + write!(f, "{}", self.offset)?; + } else { + write!(f, "{}+{:#x}", self.offset, cb.offset)?; + } + write!(f, "]") + } +} + #[repr(C)] #[derive(SrcsAsSlice, DstsAsSlice)] pub struct OpSt { @@ -2995,6 +3026,7 @@ pub enum Op { SuSt(OpSuSt), SuAtom(OpSuAtom), Ld(OpLd), + Ldc(OpLdc), St(OpSt), Atom(OpAtom), AtomCas(OpAtomCas), @@ -3547,6 +3579,7 @@ impl Instr { Op::SuSt(_) => None, Op::SuAtom(_) => None, Op::Ld(_) => None, + Op::Ldc(_) => None, Op::St(_) => None, Op::Atom(_) => None, Op::AtomCas(_) => None, diff --git a/src/nouveau/compiler/nak_legalize.rs b/src/nouveau/compiler/nak_legalize.rs index 24b3cb44b25..b821a897451 100644 --- a/src/nouveau/compiler/nak_legalize.rs +++ b/src/nouveau/compiler/nak_legalize.rs @@ -225,6 +225,7 @@ impl<'a> LegalizeInstr<'a> { self.mov_src_if_not_reg(src0, RegFile::GPR); self.mov_src_if_not_reg(src2, RegFile::GPR); } + Op::Ldc(_) => (), /* Nothing to do */ _ => { let src_types = instr.src_types(); for (i, src) in instr.srcs_mut().iter_mut().enumerate() { diff --git a/src/nouveau/compiler/nak_nir.c b/src/nouveau/compiler/nak_nir.c index 33c8cc1d39d..136330acbe4 100644 --- a/src/nouveau/compiler/nak_nir.c +++ b/src/nouveau/compiler/nak_nir.c @@ -518,8 +518,10 @@ nak_mem_access_size_align(nir_intrinsic_op intrin, bytes_pow2 = 1 << (util_last_bit(bytes) - 1); } - const unsigned chunk_bytes = MIN3(bytes_pow2, align, 16); + unsigned chunk_bytes = MIN3(bytes_pow2, align, 16); assert(util_is_power_of_two_nonzero(chunk_bytes)); + if (intrin == nir_intrinsic_load_ubo) + chunk_bytes = MIN2(chunk_bytes, 8); if (chunk_bytes < 4) { return (nir_mem_access_size_align) { @@ -562,7 +564,7 @@ nak_postprocess_nir(nir_shader *nir, const struct nak_compiler *nak) } nir_lower_mem_access_bit_sizes_options mem_bit_size_options = { - .modes = nir_var_mem_generic, + .modes = nir_var_mem_ubo | nir_var_mem_generic, .callback = nak_mem_access_size_align, }; OPT(nir, nir_lower_mem_access_bit_sizes, &mem_bit_size_options);