nak: sm100+ texture encodings

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34334>
This commit is contained in:
Mel Henning 2025-04-03 16:36:02 -04:00 committed by Marge Bot
parent f70b7d10c2
commit fd90b072f1
3 changed files with 265 additions and 23 deletions

View file

@ -2104,6 +2104,18 @@ pub enum TexLodMode {
BiasClamp,
}
impl TexLodMode {
pub fn is_explicit_lod(&self) -> bool {
match self {
TexLodMode::Auto
| TexLodMode::Bias
| TexLodMode::Clamp
| TexLodMode::BiasClamp => false,
TexLodMode::Zero | TexLodMode::Lod => true,
}
}
}
impl fmt::Display for TexLodMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {

View file

@ -305,3 +305,174 @@ pub fn test_ld_st_atom() {
c.check(sm);
}
}
#[test]
pub fn test_texture() {
let r0 = RegRef::new(RegFile::GPR, 0, 1);
let r1 = RegRef::new(RegFile::GPR, 1, 1);
let r2 = RegRef::new(RegFile::GPR, 2, 1);
let r3 = RegRef::new(RegFile::GPR, 3, 1);
let p0 = RegRef::new(RegFile::Pred, 0, 1);
let lod_modes = [
TexLodMode::Auto,
TexLodMode::Zero,
TexLodMode::Lod,
TexLodMode::Bias,
TexLodMode::Clamp,
TexLodMode::BiasClamp,
];
let tld4_offset_modes = [
Tld4OffsetMode::None,
Tld4OffsetMode::AddOffI,
Tld4OffsetMode::PerPx,
];
let tex_queries = [
TexQuery::Dimension,
TexQuery::TextureType,
TexQuery::SamplerPos,
];
for sm in SM_LIST {
let mut c = DisasmCheck::new();
for lod_mode in lod_modes {
let lod_mode_str = if lod_mode == TexLodMode::Auto {
String::new()
} else {
format!(".{lod_mode}")
};
if lod_mode == TexLodMode::BiasClamp && sm >= 100 {
continue;
}
let instr = OpTex {
dsts: [Dst::Reg(r0), Dst::Reg(r2)],
fault: Dst::Reg(p0),
tex: TexRef::Bindless,
srcs: [SrcRef::Reg(r1).into(), SrcRef::Reg(r3).into()],
dim: TexDim::_2D,
lod_mode,
z_cmpr: false,
offset: false,
mem_eviction_priority: MemEvictionPriority::First,
nodep: true,
channel_mask: ChannelMask::for_comps(3),
};
c.push(
instr,
format!(
"tex.b{lod_mode_str}.ef.nodep p0, r2, r0, r1, r3, 2d, 0x7;"
),
);
if lod_mode.is_explicit_lod() {
let instr = OpTld {
dsts: [Dst::Reg(r0), Dst::Reg(r2)],
fault: Dst::Reg(p0),
tex: TexRef::Bindless,
srcs: [SrcRef::Reg(r1).into(), SrcRef::Reg(r3).into()],
dim: TexDim::_2D,
is_ms: false,
lod_mode,
offset: false,
mem_eviction_priority: MemEvictionPriority::First,
nodep: true,
channel_mask: ChannelMask::for_comps(3),
};
c.push(
instr,
format!("tld.b{lod_mode_str}.ef.nodep p0, r2, r0, r1, r3, 2d, 0x7;"),
);
}
}
for offset_mode in tld4_offset_modes {
let offset_mode_str = if offset_mode == Tld4OffsetMode::None {
String::new()
} else {
format!(".{offset_mode}")
};
let instr = OpTld4 {
dsts: [Dst::Reg(r0), Dst::Reg(r2)],
fault: Dst::Reg(p0),
tex: TexRef::Bindless,
srcs: [SrcRef::Reg(r1).into(), SrcRef::Reg(r3).into()],
dim: TexDim::_2D,
comp: 1,
offset_mode,
z_cmpr: false,
mem_eviction_priority: MemEvictionPriority::First,
nodep: true,
channel_mask: ChannelMask::for_comps(3),
};
c.push(
instr,
format!("tld4.g.b{offset_mode_str}.ef.nodep p0, r2, r0, r1, r3, 2d, 0x7;"),
);
}
let instr = OpTmml {
dsts: [Dst::Reg(r0), Dst::Reg(r2)],
tex: TexRef::Bindless,
srcs: [SrcRef::Reg(r1).into(), SrcRef::Reg(r3).into()],
dim: TexDim::_2D,
nodep: true,
channel_mask: ChannelMask::for_comps(3),
};
c.push(instr, format!("tmml.b.lod.nodep r2, r0, r1, r3, 2d, 0x7;"));
let instr = OpTxd {
dsts: [Dst::Reg(r0), Dst::Reg(r2)],
fault: Dst::Reg(p0),
tex: TexRef::Bindless,
srcs: [SrcRef::Reg(r1).into(), SrcRef::Reg(r3).into()],
dim: TexDim::_2D,
offset: false,
mem_eviction_priority: MemEvictionPriority::First,
nodep: true,
channel_mask: ChannelMask::for_comps(3),
};
c.push(
instr,
format!("txd.b.ef.nodep p0, r2, r0, r1, r3, 2d, 0x7;"),
);
for tex_query in tex_queries {
let instr = OpTxq {
dsts: [Dst::Reg(r0), Dst::Reg(r2)],
tex: TexRef::Bindless,
src: SrcRef::Reg(r1).into(),
query: tex_query,
nodep: true,
channel_mask: ChannelMask::for_comps(3),
};
c.push(
instr,
format!("txq.b.nodep r2, r0, r1, tex_header_{tex_query}, 0x7;"),
);
}
c.check(sm);
}
}

View file

@ -2306,17 +2306,36 @@ impl SM70Encoder<'_> {
fn set_tex_lod_mode(&mut self, range: Range<usize>, lod_mode: TexLodMode) {
assert!(range.len() == 3);
self.set_field(
range,
match lod_mode {
TexLodMode::Auto => 0_u8,
TexLodMode::Zero => 1_u8,
TexLodMode::Bias => 2_u8,
TexLodMode::Lod => 3_u8,
TexLodMode::Clamp => 4_u8,
TexLodMode::BiasClamp => 5_u8,
},
);
if self.sm >= 100 {
self.set_field(
range,
match lod_mode {
TexLodMode::Auto => 0_u8,
TexLodMode::Bias => 1_u8,
TexLodMode::Clamp => 2_u8,
// ulb => 0x3
// ulc => 0x4
// lb.ulc => 0x5
TexLodMode::BiasClamp => todo!(),
TexLodMode::Zero => 0_u8,
TexLodMode::Lod => 1_u8,
// ull => 3
},
);
} else {
self.set_field(
range,
match lod_mode {
TexLodMode::Auto => 0_u8,
TexLodMode::Zero => 1_u8,
TexLodMode::Bias => 2_u8,
TexLodMode::Lod => 3_u8,
TexLodMode::Clamp => 4_u8,
TexLodMode::BiasClamp => 5_u8,
},
);
}
}
fn set_image_dim(&mut self, range: Range<usize>, dim: ImageDim) {
@ -2384,12 +2403,18 @@ impl SM70Op for OpTex {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
assert!(e.sm < 100);
e.set_opcode(0xb60);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x361);
e.set_bit(59, true); // .B
if e.sm >= 100 {
e.set_opcode(0xd61);
e.set_bit(91, true);
} else {
e.set_opcode(0x361);
e.set_bit(59, true); // .B
}
}
}
@ -2404,6 +2429,11 @@ impl SM70Op for OpTex {
e.set_reg_src(24..32, self.srcs[0]);
e.set_reg_src(32..40, self.srcs[1]);
if e.sm >= 100 {
e.set_field(48..56, 0xff_u8); // ureg
e.set_bit(59, self.lod_mode.is_explicit_lod());
}
e.set_tex_dim(61..64, self.dim);
e.set_tex_channel_mask(72..76, self.channel_mask);
e.set_bit(76, self.offset);
@ -2426,12 +2456,18 @@ impl SM70Op for OpTld {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
assert!(e.sm < 100);
e.set_opcode(0xb66);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x367);
e.set_bit(59, true); // .B
if e.sm >= 100 {
e.set_opcode(0xd67);
e.set_bit(91, true);
} else {
e.set_opcode(0x367);
e.set_bit(59, true); // .B
}
}
}
@ -2446,17 +2482,18 @@ impl SM70Op for OpTld {
e.set_reg_src(24..32, self.srcs[0]);
e.set_reg_src(32..40, self.srcs[1]);
if e.sm >= 100 {
e.set_field(48..56, 0xff_u8); // ureg
}
e.set_tex_dim(61..64, self.dim);
e.set_tex_channel_mask(72..76, self.channel_mask);
e.set_bit(76, self.offset);
// bit 77: .CL
e.set_bit(78, self.is_ms);
// bits 79..81: .F16
assert!(
self.lod_mode == TexLodMode::Zero
|| self.lod_mode == TexLodMode::Lod
);
e.set_eviction_priority(&self.mem_eviction_priority);
assert!(self.lod_mode.is_explicit_lod());
e.set_tex_lod_mode(87..90, self.lod_mode);
e.set_bit(90, self.nodep);
}
@ -2473,12 +2510,18 @@ impl SM70Op for OpTld4 {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
assert!(e.sm < 100);
e.set_opcode(0xb63);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x364);
e.set_bit(59, true); // .B
if e.sm >= 100 {
e.set_opcode(0xd64);
e.set_bit(91, true);
} else {
e.set_opcode(0x364);
e.set_bit(59, true); // .B
}
}
}
@ -2493,6 +2536,10 @@ impl SM70Op for OpTld4 {
e.set_reg_src(24..32, self.srcs[0]);
e.set_reg_src(32..40, self.srcs[1]);
if e.sm >= 100 {
e.set_field(48..56, 0xff_u8); // ureg
}
e.set_tex_dim(61..64, self.dim);
e.set_tex_channel_mask(72..76, self.channel_mask);
e.set_field(
@ -2522,6 +2569,7 @@ impl SM70Op for OpTmml {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
assert!(e.sm < 100);
e.set_opcode(0xb69);
e.set_tex_cb_ref(40..59, cb);
}
@ -2559,12 +2607,18 @@ impl SM70Op for OpTxd {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
assert!(e.sm < 100);
e.set_opcode(0xb6c);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x36d);
e.set_bit(59, true); // .B
if e.sm >= 100 {
e.set_opcode(0xd6d);
e.set_bit(91, true);
} else {
e.set_opcode(0x36d);
e.set_bit(59, true); // .B
}
}
}
@ -2579,6 +2633,10 @@ impl SM70Op for OpTxd {
e.set_reg_src(24..32, self.srcs[0]);
e.set_reg_src(32..40, self.srcs[1]);
if e.sm >= 100 {
e.set_field(48..56, 0xff_u8); // ureg
}
e.set_tex_dim(61..64, self.dim);
e.set_tex_channel_mask(72..76, self.channel_mask);
e.set_bit(76, self.offset);
@ -2599,6 +2657,7 @@ impl SM70Op for OpTxq {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
assert!(e.sm < 100);
e.set_opcode(0xb6f);
e.set_tex_cb_ref(40..59, cb);
}