diff --git a/src/nouveau/compiler/nak_encode_sm75.rs b/src/nouveau/compiler/nak_encode_sm75.rs index a5aa4395c84..9111028ff0d 100644 --- a/src/nouveau/compiler/nak_encode_sm75.rs +++ b/src/nouveau/compiler/nak_encode_sm75.rs @@ -1480,6 +1480,12 @@ impl SM75Instr { self.set_pred_src(87..90, 90, SrcRef::True.into()); } + fn encode_cs2r(&mut self, op: &OpCS2R) { + self.set_opcode(0x805); + self.set_dst(op.dst); + self.set_field(72..80, op.idx); + } + fn encode_s2r(&mut self, op: &OpS2R) { self.set_opcode(0x919); self.set_dst(op.dst); @@ -1591,6 +1597,7 @@ impl SM75Instr { Op::Bra(op) => si.encode_bra(&op, ip, block_offsets), Op::Exit(op) => si.encode_exit(&op), Op::Bar(op) => si.encode_bar(&op), + Op::CS2R(op) => si.encode_cs2r(&op), Op::S2R(op) => si.encode_s2r(&op), Op::PopC(op) => si.encode_popc(&op), Op::Brev(op) => si.encode_brev(&op), diff --git a/src/nouveau/compiler/nak_from_nir.rs b/src/nouveau/compiler/nak_from_nir.rs index 64f9a188e46..ca75f02d9d1 100644 --- a/src/nouveau/compiler/nak_from_nir.rs +++ b/src/nouveau/compiler/nak_from_nir.rs @@ -1285,12 +1285,21 @@ impl<'a> ShaderFromNir<'a> { } nir_intrinsic_load_sysval_nv => { let idx = u8::try_from(intrin.base()).unwrap(); - let dst = b.alloc_ssa(RegFile::GPR, 1); - - b.push_op(OpS2R { - dst: dst.into(), - idx: idx, - }); + debug_assert!(intrin.def.num_components == 1); + let dst = b.alloc_ssa(RegFile::GPR, intrin.def.bit_size() / 32); + if intrin.def.bit_size() == 32 { + b.push_op(OpS2R { + dst: dst.into(), + idx: idx, + }); + } else if intrin.def.bit_size() == 64 { + b.push_op(OpCS2R { + dst: dst.into(), + idx: idx, + }); + } else { + panic!("Unknown sysval_nv bit size"); + } self.set_dst(&intrin.def, dst); } nir_intrinsic_load_ubo => { diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs index ee4915fef38..c5bf0e80d3c 100644 --- a/src/nouveau/compiler/nak_ir.rs +++ b/src/nouveau/compiler/nak_ir.rs @@ -3040,6 +3040,19 @@ impl fmt::Display for OpBar { } } +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpCS2R { + pub dst: Dst, + pub idx: u8, +} + +impl fmt::Display for OpCS2R { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "CS2R {} sr[{:#x}]", self.dst, self.idx) + } +} + #[repr(C)] #[derive(SrcsAsSlice, DstsAsSlice)] pub struct OpS2R { @@ -3586,6 +3599,7 @@ pub enum Op { Bra(OpBra), Exit(OpExit), Bar(OpBar), + CS2R(OpCS2R), S2R(OpS2R), Undef(OpUndef), PhiSrcs(OpPhiSrcs), @@ -3938,6 +3952,7 @@ impl Instr { Some(15) } Op::Sel(_) => Some(15), + Op::CS2R(_) => None, Op::S2R(_) => None, Op::ALd(_) => None, Op::ASt(_) => Some(15), diff --git a/src/nouveau/compiler/nak_nir.c b/src/nouveau/compiler/nak_nir.c index dc007226c12..f82ff621e65 100644 --- a/src/nouveau/compiler/nak_nir.c +++ b/src/nouveau/compiler/nak_nir.c @@ -482,6 +482,11 @@ nak_nir_lower_system_value_instr(nir_builder *b, nir_instr *instr, void *data) break; } + case nir_intrinsic_shader_clock: + val = nir_load_sysval_nv(b, 64, .base = 0x50); + val = nir_unpack_64_2x32(b, val); + break; + default: return false; }