nak: Implement indirect UBO loads

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-05-05 22:08:14 -05:00 committed by Marge Bot
parent 0ff7fbf093
commit 3bf0882ea8
5 changed files with 63 additions and 3 deletions

View file

@ -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),

View file

@ -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");

View file

@ -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,

View file

@ -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() {

View file

@ -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);