mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 19:40:10 +01:00
nak: sm100+ texture encodings
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34334>
This commit is contained in:
parent
f70b7d10c2
commit
fd90b072f1
3 changed files with 265 additions and 23 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue