diff --git a/src/nouveau/compiler/nak/from_nir.rs b/src/nouveau/compiler/nak/from_nir.rs index d74eadd05aa..e69ab96c916 100644 --- a/src/nouveau/compiler/nak/from_nir.rs +++ b/src/nouveau/compiler/nak/from_nir.rs @@ -1774,6 +1774,7 @@ impl<'a> ShaderFromNir<'a> { assert!(fault.is_none()); b.push_op(OpTxq { dsts: dsts, + tex: TexRef::Bindless, src: src, query: TexQuery::Dimension, mask: mask, @@ -1783,6 +1784,7 @@ impl<'a> ShaderFromNir<'a> { assert!(fault.is_none()); b.push_op(OpTxq { dsts: dsts, + tex: TexRef::Bindless, src: src, query: TexQuery::TextureType, mask: mask, @@ -1814,6 +1816,7 @@ impl<'a> ShaderFromNir<'a> { b.push_op(OpTxd { dsts: dsts, fault, + tex: TexRef::Bindless, srcs: srcs, dim: dim, offset: offset_mode == Tld4OffsetMode::AddOffI, @@ -1823,6 +1826,7 @@ impl<'a> ShaderFromNir<'a> { assert!(offset_mode == Tld4OffsetMode::None); b.push_op(OpTmml { dsts: dsts, + tex: TexRef::Bindless, srcs: srcs, dim: dim, mask: mask, @@ -1832,6 +1836,7 @@ impl<'a> ShaderFromNir<'a> { b.push_op(OpTld { dsts: dsts, fault, + tex: TexRef::Bindless, srcs: srcs, dim: dim, lod_mode: lod_mode, @@ -1843,6 +1848,7 @@ impl<'a> ShaderFromNir<'a> { b.push_op(OpTld4 { dsts: dsts, fault, + tex: TexRef::Bindless, srcs: srcs, dim: dim, comp: tex.component().try_into().unwrap(), @@ -1855,6 +1861,7 @@ impl<'a> ShaderFromNir<'a> { b.push_op(OpTex { dsts: dsts, fault, + tex: TexRef::Bindless, srcs: srcs, dim: dim, lod_mode: lod_mode, diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index b13a9bd867e..d6cecac9783 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -2034,6 +2034,32 @@ impl fmt::Display for FRndMode { } } +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct TexCBufRef { + pub idx: u8, + pub offset: u16, +} + +#[allow(dead_code)] +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum TexRef { + Bound(u16), + CBuf(TexCBufRef), + Bindless, +} + +impl fmt::Display for TexRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TexRef::Bound(idx) => write!(f, "tex[{idx}]"), + TexRef::CBuf(TexCBufRef { idx, offset }) => { + write!(f, "c[{idx:#x}][{offset:#x}]") + } + TexRef::Bindless => write!(f, "bindless"), + } + } +} + #[derive(Clone, Copy, Eq, PartialEq)] pub enum TexDim { _1D, @@ -4636,6 +4662,8 @@ pub struct OpTex { pub dsts: [Dst; 2], pub fault: Dst, + pub tex: TexRef, + #[src_type(SSA)] pub srcs: [Src; 2], @@ -4648,7 +4676,7 @@ pub struct OpTex { impl DisplayOp for OpTex { fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "tex.b{}", self.dim)?; + write!(f, "tex{}", self.dim)?; if self.lod_mode != TexLodMode::Auto { write!(f, ".{}", self.lod_mode)?; } @@ -4658,7 +4686,7 @@ impl DisplayOp for OpTex { if self.z_cmpr { write!(f, ".dc")?; } - write!(f, " {} {}", self.srcs[0], self.srcs[1]) + write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1]) } } impl_display_for_op!(OpTex); @@ -4669,6 +4697,8 @@ pub struct OpTld { pub dsts: [Dst; 2], pub fault: Dst, + pub tex: TexRef, + #[src_type(SSA)] pub srcs: [Src; 2], @@ -4681,7 +4711,7 @@ pub struct OpTld { impl DisplayOp for OpTld { fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "tld.b{}", self.dim)?; + write!(f, "tld{}", self.dim)?; if self.lod_mode != TexLodMode::Auto { write!(f, ".{}", self.lod_mode)?; } @@ -4691,7 +4721,7 @@ impl DisplayOp for OpTld { if self.is_ms { write!(f, ".ms")?; } - write!(f, " {} {}", self.srcs[0], self.srcs[1]) + write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1]) } } impl_display_for_op!(OpTld); @@ -4702,6 +4732,8 @@ pub struct OpTld4 { pub dsts: [Dst; 2], pub fault: Dst, + pub tex: TexRef, + #[src_type(SSA)] pub srcs: [Src; 2], @@ -4714,11 +4746,11 @@ pub struct OpTld4 { impl DisplayOp for OpTld4 { fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "tld4.g.b{}", self.dim)?; + write!(f, "tld4.g{}", self.dim)?; if self.offset_mode != Tld4OffsetMode::None { write!(f, ".{}", self.offset_mode)?; } - write!(f, " {} {}", self.srcs[0], self.srcs[1]) + write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1]) } } impl_display_for_op!(OpTld4); @@ -4728,6 +4760,8 @@ impl_display_for_op!(OpTld4); pub struct OpTmml { pub dsts: [Dst; 2], + pub tex: TexRef, + #[src_type(SSA)] pub srcs: [Src; 2], @@ -4739,8 +4773,8 @@ impl DisplayOp for OpTmml { fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "tmml.b.lod{} {} {}", - self.dim, self.srcs[0], self.srcs[1] + "tmml.lod{} {} {} {}", + self.dim, self.tex, self.srcs[0], self.srcs[1] ) } } @@ -4752,6 +4786,8 @@ pub struct OpTxd { pub dsts: [Dst; 2], pub fault: Dst, + pub tex: TexRef, + #[src_type(SSA)] pub srcs: [Src; 2], @@ -4762,11 +4798,11 @@ pub struct OpTxd { impl DisplayOp for OpTxd { fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "txd.b{}", self.dim)?; + write!(f, "txd{}", self.dim)?; if self.offset { write!(f, ".aoffi")?; } - write!(f, " {} {}", self.srcs[0], self.srcs[1]) + write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1]) } } impl_display_for_op!(OpTxd); @@ -4776,6 +4812,8 @@ impl_display_for_op!(OpTxd); pub struct OpTxq { pub dsts: [Dst; 2], + pub tex: TexRef, + #[src_type(SSA)] pub src: Src, @@ -4785,7 +4823,7 @@ pub struct OpTxq { impl DisplayOp for OpTxq { fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "txq.b {} {}", self.src, self.query) + write!(f, "txq {} {} {}", self.tex, self.src, self.query) } } impl_display_for_op!(OpTxq); diff --git a/src/nouveau/compiler/nak/sm50.rs b/src/nouveau/compiler/nak/sm50.rs index 684d5f565e6..d81a71c6175 100644 --- a/src/nouveau/compiler/nak/sm50.rs +++ b/src/nouveau/compiler/nak/sm50.rs @@ -2050,7 +2050,22 @@ impl SM50Op for OpTex { } fn encode(&self, e: &mut SM50Encoder<'_>) { - e.set_opcode(0xdeb8); + match self.tex { + TexRef::Bound(idx) => { + e.set_opcode(0x0380); + e.set_field(36..49, idx); + e.set_bit(54, self.offset); + e.set_tex_lod_mode(55..57, self.lod_mode); + } + TexRef::CBuf { .. } => { + panic!("SM50 doesn't have CBuf textures"); + } + TexRef::Bindless => { + e.set_opcode(0xdeb8); + e.set_bit(36, self.offset); + e.set_tex_lod_mode(37..39, self.lod_mode); + } + } e.set_dst(self.dsts[0]); assert!(self.dsts[1].is_none()); @@ -2061,8 +2076,6 @@ impl SM50Op for OpTex { e.set_tex_dim(28..31, self.dim); e.set_field(31..35, self.mask); e.set_bit(35, false); // ToDo: NDV - e.set_bit(36, self.offset); - e.set_tex_lod_mode(37..39, self.lod_mode); e.set_bit(49, false); // TODO: .NODEP e.set_bit(50, self.z_cmpr); } @@ -2074,7 +2087,18 @@ impl SM50Op for OpTld { } fn encode(&self, e: &mut SM50Encoder<'_>) { - e.set_opcode(0xdd38); + match self.tex { + TexRef::Bound(idx) => { + e.set_opcode(0xdc38); + e.set_field(36..49, idx); + } + TexRef::CBuf { .. } => { + panic!("SM50 doesn't have CBuf textures"); + } + TexRef::Bindless => { + e.set_opcode(0xdd38); + } + } e.set_dst(self.dsts[0]); assert!(self.dsts[1].is_none()); @@ -2102,7 +2126,27 @@ impl SM50Op for OpTld4 { } fn encode(&self, e: &mut SM50Encoder<'_>) { - e.set_opcode(0xdef8); + let offset_mode = match self.offset_mode { + Tld4OffsetMode::None => 0_u8, + Tld4OffsetMode::AddOffI => 1_u8, + Tld4OffsetMode::PerPx => 2_u8, + }; + match self.tex { + TexRef::Bound(idx) => { + e.set_opcode(0xc838); + e.set_field(36..49, idx); + e.set_field(54..56, offset_mode); + e.set_field(56..58, self.comp); + } + TexRef::CBuf { .. } => { + panic!("SM50 doesn't have CBuf textures"); + } + TexRef::Bindless => { + e.set_opcode(0xdef8); + e.set_field(36..38, offset_mode); + e.set_field(38..40, self.comp); + } + } e.set_dst(self.dsts[0]); assert!(self.dsts[1].is_none()); @@ -2113,15 +2157,6 @@ impl SM50Op for OpTld4 { e.set_tex_dim(28..31, self.dim); e.set_field(31..35, self.mask); e.set_bit(35, false); // ToDo: NDV - e.set_field( - 36..38, - match self.offset_mode { - Tld4OffsetMode::None => 0_u8, - Tld4OffsetMode::AddOffI => 1_u8, - Tld4OffsetMode::PerPx => 2_u8, - }, - ); - e.set_field(38..40, self.comp); e.set_bit(49, false); // TODO: .NODEP e.set_bit(50, self.z_cmpr); } @@ -2133,7 +2168,18 @@ impl SM50Op for OpTmml { } fn encode(&self, e: &mut SM50Encoder<'_>) { - e.set_opcode(0xdf60); + match self.tex { + TexRef::Bound(idx) => { + e.set_opcode(0xdf58); + e.set_field(36..49, idx); + } + TexRef::CBuf { .. } => { + panic!("SM50 doesn't have CBuf textures"); + } + TexRef::Bindless => { + e.set_opcode(0xdf60); + } + } e.set_dst(self.dsts[0]); assert!(self.dsts[1].is_none()); @@ -2153,7 +2199,18 @@ impl SM50Op for OpTxd { } fn encode(&self, e: &mut SM50Encoder<'_>) { - e.set_opcode(0xde78); + match self.tex { + TexRef::Bound(idx) => { + e.set_opcode(0xde38); + e.set_field(36..49, idx); + } + TexRef::CBuf { .. } => { + panic!("SM50 doesn't have CBuf textures"); + } + TexRef::Bindless => { + e.set_opcode(0xde78); + } + } e.set_dst(self.dsts[0]); assert!(self.dsts[1].is_none()); @@ -2174,7 +2231,18 @@ impl SM50Op for OpTxq { } fn encode(&self, e: &mut SM50Encoder<'_>) { - e.set_opcode(0xdf50); + match self.tex { + TexRef::Bound(idx) => { + e.set_opcode(0xdf48); + e.set_field(36..49, idx); + } + TexRef::CBuf { .. } => { + panic!("SM50 doesn't have CBuf textures"); + } + TexRef::Bindless => { + e.set_opcode(0xdf50); + } + } e.set_dst(self.dsts[0]); assert!(self.dsts[1].is_none()); diff --git a/src/nouveau/compiler/nak/sm70.rs b/src/nouveau/compiler/nak/sm70.rs index e1a8d788ba0..3b12d9c7916 100644 --- a/src/nouveau/compiler/nak/sm70.rs +++ b/src/nouveau/compiler/nak/sm70.rs @@ -2265,6 +2265,14 @@ impl SM70Op for OpR2UR { } impl SM70Encoder<'_> { + fn set_tex_cb_ref(&mut self, range: Range, cb: TexCBufRef) { + assert!(range.len() == 19); + let mut v = BitMutView::new_subset(self, range); + assert!(cb.offset % 4 == 0); + v.set_field(0..14, cb.offset / 4); + v.set_field(14..19, cb.idx); + } + fn set_tex_dim(&mut self, range: Range, dim: TexDim) { assert!(range.len() == 3); self.set_field( @@ -2318,8 +2326,19 @@ impl SM70Op for OpTex { } fn encode(&self, e: &mut SM70Encoder<'_>) { - e.set_opcode(0x361); - e.set_bit(59, true); // .B + match self.tex { + TexRef::Bound(_) => { + panic!("SM70+ doesn't have legacy bound textures"); + } + TexRef::CBuf(cb) => { + e.set_opcode(0xb60); + e.set_tex_cb_ref(40..59, cb); + } + TexRef::Bindless => { + e.set_opcode(0x361); + e.set_bit(59, true); // .B + } + } e.set_dst(self.dsts[0]); if let Dst::Reg(reg) = self.dsts[1] { @@ -2349,8 +2368,19 @@ impl SM70Op for OpTld { } fn encode(&self, e: &mut SM70Encoder<'_>) { - e.set_opcode(0x367); - e.set_bit(59, true); // .B + match self.tex { + TexRef::Bound(_) => { + panic!("SM70+ doesn't have legacy bound textures"); + } + TexRef::CBuf(cb) => { + e.set_opcode(0xb66); + e.set_tex_cb_ref(40..59, cb); + } + TexRef::Bindless => { + e.set_opcode(0x367); + e.set_bit(59, true); // .B + } + } e.set_dst(self.dsts[0]); if let Dst::Reg(reg) = self.dsts[1] { @@ -2384,8 +2414,19 @@ impl SM70Op for OpTld4 { } fn encode(&self, e: &mut SM70Encoder<'_>) { - e.set_opcode(0x364); - e.set_bit(59, true); // .B + match self.tex { + TexRef::Bound(_) => { + panic!("SM70+ doesn't have legacy bound textures"); + } + TexRef::CBuf(cb) => { + e.set_opcode(0xb63); + e.set_tex_cb_ref(40..59, cb); + } + TexRef::Bindless => { + e.set_opcode(0x364); + e.set_bit(59, true); // .B + } + } e.set_dst(self.dsts[0]); if let Dst::Reg(reg) = self.dsts[1] { @@ -2422,8 +2463,19 @@ impl SM70Op for OpTmml { } fn encode(&self, e: &mut SM70Encoder<'_>) { - e.set_opcode(0x36a); - e.set_bit(59, true); // .B + match self.tex { + TexRef::Bound(_) => { + panic!("SM70+ doesn't have legacy bound textures"); + } + TexRef::CBuf(cb) => { + e.set_opcode(0xb69); + e.set_tex_cb_ref(40..59, cb); + } + TexRef::Bindless => { + e.set_opcode(0x36a); + e.set_bit(59, true); // .B + } + } e.set_dst(self.dsts[0]); if let Dst::Reg(reg) = self.dsts[1] { @@ -2448,8 +2500,19 @@ impl SM70Op for OpTxd { } fn encode(&self, e: &mut SM70Encoder<'_>) { - e.set_opcode(0x36d); - e.set_bit(59, true); // .B + match self.tex { + TexRef::Bound(_) => { + panic!("SM70+ doesn't have legacy bound textures"); + } + TexRef::CBuf(cb) => { + e.set_opcode(0xb6c); + e.set_tex_cb_ref(40..59, cb); + } + TexRef::Bindless => { + e.set_opcode(0x36d); + e.set_bit(59, true); // .B + } + } e.set_dst(self.dsts[0]); if let Dst::Reg(reg) = self.dsts[1] { @@ -2476,8 +2539,19 @@ impl SM70Op for OpTxq { } fn encode(&self, e: &mut SM70Encoder<'_>) { - e.set_opcode(0x370); - e.set_bit(59, true); // .B + match self.tex { + TexRef::Bound(_) => { + panic!("SM70+ doesn't have legacy bound textures"); + } + TexRef::CBuf(cb) => { + e.set_opcode(0xb6f); + e.set_tex_cb_ref(40..59, cb); + } + TexRef::Bindless => { + e.set_opcode(0x370); + e.set_bit(59, true); // .B + } + } e.set_dst(self.dsts[0]); if let Dst::Reg(reg) = self.dsts[1] {