mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 03:00:24 +01:00
nak: Wire up texture ops
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
parent
9d7e1d515f
commit
a70423944b
3 changed files with 648 additions and 2 deletions
|
|
@ -735,6 +735,187 @@ impl SM75Instr {
|
|||
self.set_pred_src(87..90, 90, op.srcs[0]);
|
||||
}
|
||||
|
||||
fn set_tex_dim(&mut self, range: Range<usize>, dim: TexDim) {
|
||||
assert!(range.len() == 3);
|
||||
self.set_field(
|
||||
range,
|
||||
match dim {
|
||||
TexDim::_1D => 0_u8,
|
||||
TexDim::Array1D => 4_u8,
|
||||
TexDim::_2D => 1_u8,
|
||||
TexDim::Array2D => 5_u8,
|
||||
TexDim::_3D => 2_u8,
|
||||
TexDim::Cube => 3_u8,
|
||||
TexDim::ArrayCube => 7_u8,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn encode_tex(&mut self, op: &OpTex) {
|
||||
self.set_opcode(0x361);
|
||||
self.set_bit(59, true); /* .B */
|
||||
|
||||
self.set_dst(op.dsts[0]);
|
||||
if let Dst::Reg(reg) = op.dsts[1] {
|
||||
self.set_reg(64..72, reg);
|
||||
} else {
|
||||
self.set_field(64..72, 255_u8);
|
||||
}
|
||||
self.set_pred_dst(81..84, op.resident);
|
||||
|
||||
self.set_reg_src(24..32, op.srcs[0]);
|
||||
self.set_reg_src(32..40, op.srcs[1]);
|
||||
|
||||
self.set_tex_dim(61..64, op.dim);
|
||||
self.set_field(72..76, op.mask);
|
||||
self.set_bit(76, op.offset);
|
||||
self.set_bit(77, false); /* ToDo: NDV */
|
||||
self.set_bit(78, op.z_cmpr);
|
||||
self.set_field(84..87, 1);
|
||||
self.set_tex_lod_mode(87..90, op.lod_mode);
|
||||
self.set_bit(90, false); /* TODO: .NODEP */
|
||||
}
|
||||
|
||||
fn encode_tld(&mut self, op: &OpTld) {
|
||||
self.set_opcode(0x367);
|
||||
self.set_bit(59, true); /* .B */
|
||||
|
||||
self.set_dst(op.dsts[0]);
|
||||
if let Dst::Reg(reg) = op.dsts[1] {
|
||||
self.set_reg(64..72, reg);
|
||||
} else {
|
||||
self.set_field(64..72, 255_u8);
|
||||
}
|
||||
self.set_pred_dst(81..84, op.resident);
|
||||
|
||||
self.set_reg_src(24..32, op.srcs[0]);
|
||||
self.set_reg_src(32..40, op.srcs[1]);
|
||||
|
||||
self.set_tex_dim(61..64, op.dim);
|
||||
self.set_field(72..76, op.mask);
|
||||
self.set_bit(76, op.offset);
|
||||
/* bit 77: .CL */
|
||||
self.set_bit(78, op.is_ms);
|
||||
/* bits 79..81: .F16 */
|
||||
assert!(
|
||||
op.lod_mode == TexLodMode::Zero || op.lod_mode == TexLodMode::Lod
|
||||
);
|
||||
self.set_tex_lod_mode(87..90, op.lod_mode);
|
||||
self.set_bit(90, false); /* TODO: .NODEP */
|
||||
}
|
||||
|
||||
fn encode_tld4(&mut self, op: &OpTld4) {
|
||||
self.set_opcode(0x364);
|
||||
self.set_bit(59, true); /* .B */
|
||||
|
||||
self.set_dst(op.dsts[0]);
|
||||
if let Dst::Reg(reg) = op.dsts[1] {
|
||||
self.set_reg(64..72, reg);
|
||||
} else {
|
||||
self.set_field(64..72, 255_u8);
|
||||
}
|
||||
self.set_pred_dst(81..84, op.resident);
|
||||
|
||||
self.set_reg_src(24..32, op.srcs[0]);
|
||||
self.set_reg_src(32..40, op.srcs[1]);
|
||||
|
||||
self.set_tex_dim(61..64, op.dim);
|
||||
self.set_field(72..76, op.mask);
|
||||
self.set_field(
|
||||
76..78,
|
||||
match op.offset_mode {
|
||||
Tld4OffsetMode::None => 0_u8,
|
||||
Tld4OffsetMode::AddOffI => 1_u8,
|
||||
Tld4OffsetMode::PerPx => 2_u8,
|
||||
},
|
||||
);
|
||||
/* bit 77: .CL */
|
||||
self.set_bit(78, op.z_cmpr);
|
||||
self.set_bit(84, true); /* !.EF */
|
||||
self.set_field(87..89, op.comp);
|
||||
self.set_bit(90, false); /* TODO: .NODEP */
|
||||
}
|
||||
|
||||
fn encode_tmml(&mut self, op: &OpTmml) {
|
||||
self.set_opcode(0x36a);
|
||||
self.set_bit(59, true); /* .B */
|
||||
|
||||
self.set_dst(op.dsts[0]);
|
||||
if let Dst::Reg(reg) = op.dsts[1] {
|
||||
self.set_reg(64..72, reg);
|
||||
} else {
|
||||
self.set_field(64..72, 255_u8);
|
||||
}
|
||||
|
||||
self.set_reg_src(24..32, op.srcs[0]);
|
||||
self.set_reg_src(32..40, op.srcs[1]);
|
||||
|
||||
self.set_tex_dim(61..64, op.dim);
|
||||
self.set_field(72..76, op.mask);
|
||||
self.set_bit(77, false); /* ToDo: NDV */
|
||||
self.set_bit(90, false); /* TODO: .NODEP */
|
||||
}
|
||||
|
||||
fn encode_txd(&mut self, op: &OpTxd) {
|
||||
self.set_opcode(0x36d);
|
||||
self.set_bit(59, true); /* .B */
|
||||
|
||||
self.set_dst(op.dsts[0]);
|
||||
if let Dst::Reg(reg) = op.dsts[1] {
|
||||
self.set_reg(64..72, reg);
|
||||
} else {
|
||||
self.set_field(64..72, 255_u8);
|
||||
}
|
||||
self.set_pred_dst(81..84, op.resident);
|
||||
|
||||
self.set_reg_src(24..32, op.srcs[0]);
|
||||
self.set_reg_src(32..40, op.srcs[1]);
|
||||
|
||||
self.set_tex_dim(61..64, op.dim);
|
||||
self.set_field(72..76, op.mask);
|
||||
self.set_bit(76, op.offset);
|
||||
self.set_bit(77, false); /* ToDo: NDV */
|
||||
self.set_bit(90, false); /* TODO: .NODEP */
|
||||
}
|
||||
|
||||
fn encode_txq(&mut self, op: &OpTxq) {
|
||||
self.set_opcode(0x370);
|
||||
self.set_bit(59, true); /* .B */
|
||||
|
||||
self.set_dst(op.dsts[0]);
|
||||
if let Dst::Reg(reg) = op.dsts[1] {
|
||||
self.set_reg(64..72, reg);
|
||||
} else {
|
||||
self.set_field(64..72, 255_u8);
|
||||
}
|
||||
|
||||
self.set_reg_src(24..32, op.src);
|
||||
self.set_field(
|
||||
62..64,
|
||||
match op.query {
|
||||
TexQuery::Dimension => 0_u8,
|
||||
TexQuery::TextureType => 1_u8,
|
||||
TexQuery::SamplerPos => 2_u8,
|
||||
},
|
||||
);
|
||||
self.set_field(72..76, op.mask);
|
||||
}
|
||||
|
||||
fn set_mem_access(&mut self, access: &MemAccess) {
|
||||
self.set_field(
|
||||
72..73,
|
||||
|
|
@ -931,6 +1112,12 @@ impl SM75Instr {
|
|||
Op::Mov(op) => si.encode_mov(&op),
|
||||
Op::Sel(op) => si.encode_sel(&op),
|
||||
Op::PLop3(op) => si.encode_plop3(&op),
|
||||
Op::Tex(op) => si.encode_tex(&op),
|
||||
Op::Tld(op) => si.encode_tld(&op),
|
||||
Op::Tld4(op) => si.encode_tld4(&op),
|
||||
Op::Tmml(op) => si.encode_tmml(&op),
|
||||
Op::Txd(op) => si.encode_txd(&op),
|
||||
Op::Txq(op) => si.encode_txq(&op),
|
||||
Op::Ld(op) => si.encode_ld(&op),
|
||||
Op::St(op) => si.encode_st(&op),
|
||||
Op::ALd(op) => si.encode_ald(&op),
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
*/
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(unstable_name_collisions)]
|
||||
|
||||
use crate::nak_ir::*;
|
||||
use crate::nir::*;
|
||||
use crate::util::DivCeil;
|
||||
|
||||
use nak_bindings::*;
|
||||
|
||||
use std::cmp::min;
|
||||
use std::collections::HashMap;
|
||||
|
||||
struct ShaderFromNir<'a> {
|
||||
|
|
@ -128,6 +131,29 @@ impl<'a> ShaderFromNir<'a> {
|
|||
split
|
||||
}
|
||||
|
||||
fn split(&mut self, ssa: SSAValue) -> Vec<SSAValue> {
|
||||
if ssa.comps() == 1 {
|
||||
return vec![ssa];
|
||||
}
|
||||
|
||||
let mut split_ssa = Vec::new();
|
||||
let mut dsts = Vec::new();
|
||||
for c in 0..ssa.comps() {
|
||||
let dst_ssa = self.alloc_ssa(ssa.file(), 1);
|
||||
split_ssa.push(dst_ssa);
|
||||
dsts.push(Dst::from(dst_ssa));
|
||||
}
|
||||
self.instrs.push(Instr::new_split(&dsts, ssa.into()));
|
||||
split_ssa
|
||||
}
|
||||
|
||||
fn vec(&mut self, ssa: &[SSAValue]) -> SSAValue {
|
||||
let dst = self.alloc_ssa(ssa[0].file(), ssa.len().try_into().unwrap());
|
||||
let srcs: Vec<Src> = ssa.iter().map(|s| (*s).into()).collect();
|
||||
self.instrs.push(Instr::new_vec(dst.into(), &srcs));
|
||||
dst
|
||||
}
|
||||
|
||||
fn parse_alu(&mut self, alu: &nir_alu_instr) {
|
||||
let mut srcs = Vec::new();
|
||||
for alu_src in alu.srcs_as_slice() {
|
||||
|
|
@ -567,8 +593,171 @@ impl<'a> ShaderFromNir<'a> {
|
|||
/* Nothing to do */
|
||||
}
|
||||
|
||||
fn parse_tex(&mut self, _tex: &nir_tex_instr) {
|
||||
panic!("Texture instructions unimplemented");
|
||||
fn parse_tex(&mut self, tex: &nir_tex_instr) {
|
||||
let dim = match tex.sampler_dim {
|
||||
GLSL_SAMPLER_DIM_1D => {
|
||||
if tex.is_array {
|
||||
TexDim::Array1D
|
||||
} else {
|
||||
TexDim::_1D
|
||||
}
|
||||
}
|
||||
GLSL_SAMPLER_DIM_2D => {
|
||||
if tex.is_array {
|
||||
TexDim::Array2D
|
||||
} else {
|
||||
TexDim::_2D
|
||||
}
|
||||
}
|
||||
GLSL_SAMPLER_DIM_3D => {
|
||||
assert!(!tex.is_array);
|
||||
TexDim::_3D
|
||||
}
|
||||
GLSL_SAMPLER_DIM_CUBE => {
|
||||
if tex.is_array {
|
||||
TexDim::ArrayCube
|
||||
} else {
|
||||
TexDim::Cube
|
||||
}
|
||||
}
|
||||
GLSL_SAMPLER_DIM_BUF => TexDim::_1D,
|
||||
GLSL_SAMPLER_DIM_MS => {
|
||||
if tex.is_array {
|
||||
TexDim::Array2D
|
||||
} else {
|
||||
TexDim::_2D
|
||||
}
|
||||
}
|
||||
_ => panic!("Unsupported texture dimension: {}", tex.sampler_dim),
|
||||
};
|
||||
|
||||
let srcs = tex.srcs_as_slice();
|
||||
assert!(srcs[0].src_type == nir_tex_src_backend1);
|
||||
if srcs.len() > 1 {
|
||||
assert!(srcs.len() == 2);
|
||||
assert!(srcs[1].src_type == nir_tex_src_backend2);
|
||||
}
|
||||
|
||||
let flags: nak_nir_tex_flags =
|
||||
unsafe { std::mem::transmute_copy(&tex.backend_flags) };
|
||||
|
||||
let mask = tex.def.components_read();
|
||||
let mask = u8::try_from(mask).unwrap();
|
||||
|
||||
let dst_comps = u8::try_from(mask.count_ones()).unwrap();
|
||||
let mut dsts = [Dst::None; 2];
|
||||
dsts[0] = self.alloc_ssa(RegFile::GPR, min(dst_comps, 2)).into();
|
||||
if dst_comps > 2 {
|
||||
dsts[1] = self.alloc_ssa(RegFile::GPR, dst_comps - 2).into();
|
||||
}
|
||||
|
||||
if tex.op == nir_texop_hdr_dim_nv {
|
||||
self.instrs.push(Instr::new(Op::Txq(OpTxq {
|
||||
dsts: dsts,
|
||||
src: self.get_src(&srcs[0].src),
|
||||
query: TexQuery::Dimension,
|
||||
mask: mask,
|
||||
})));
|
||||
} else if tex.op == nir_texop_tex_type_nv {
|
||||
self.instrs.push(Instr::new(Op::Txq(OpTxq {
|
||||
dsts: dsts,
|
||||
src: self.get_src(&srcs[0].src),
|
||||
query: TexQuery::TextureType,
|
||||
mask: mask,
|
||||
})));
|
||||
} else {
|
||||
let lod_mode = match flags.lod_mode() {
|
||||
NAK_NIR_LOD_MODE_AUTO => TexLodMode::Auto,
|
||||
NAK_NIR_LOD_MODE_ZERO => TexLodMode::Zero,
|
||||
NAK_NIR_LOD_MODE_BIAS => TexLodMode::Bias,
|
||||
NAK_NIR_LOD_MODE_LOD => TexLodMode::Lod,
|
||||
NAK_NIR_LOD_MODE_CLAMP => TexLodMode::Clamp,
|
||||
NAK_NIR_LOD_MODE_BIAS_CLAMP => TexLodMode::BiasClamp,
|
||||
_ => panic!("Invalid LOD mode"),
|
||||
};
|
||||
|
||||
let offset_mode = match flags.offset_mode() {
|
||||
NAK_NIR_OFFSET_MODE_NONE => Tld4OffsetMode::None,
|
||||
NAK_NIR_OFFSET_MODE_AOFFI => Tld4OffsetMode::AddOffI,
|
||||
NAK_NIR_OFFSET_MODE_PER_PX => Tld4OffsetMode::PerPx,
|
||||
_ => panic!("Invalid offset mode"),
|
||||
};
|
||||
|
||||
let srcs = [self.get_src(&srcs[0].src), self.get_src(&srcs[1].src)];
|
||||
|
||||
if tex.op == nir_texop_txd {
|
||||
assert!(lod_mode == TexLodMode::Auto);
|
||||
assert!(offset_mode != Tld4OffsetMode::PerPx);
|
||||
assert!(!flags.has_z_cmpr());
|
||||
self.instrs.push(Instr::new(Op::Txd(OpTxd {
|
||||
dsts: dsts,
|
||||
resident: Dst::None,
|
||||
srcs: srcs,
|
||||
dim: dim,
|
||||
offset: offset_mode == Tld4OffsetMode::AddOffI,
|
||||
mask: mask,
|
||||
})));
|
||||
} else if tex.op == nir_texop_lod {
|
||||
assert!(offset_mode == Tld4OffsetMode::None);
|
||||
self.instrs.push(Instr::new(Op::Tmml(OpTmml {
|
||||
dsts: dsts,
|
||||
srcs: srcs,
|
||||
dim: dim,
|
||||
mask: mask,
|
||||
})));
|
||||
} else if tex.op == nir_texop_txf {
|
||||
assert!(offset_mode != Tld4OffsetMode::PerPx);
|
||||
self.instrs.push(Instr::new(Op::Tld(OpTld {
|
||||
dsts: dsts,
|
||||
resident: Dst::None,
|
||||
srcs: srcs,
|
||||
dim: dim,
|
||||
lod_mode: lod_mode,
|
||||
is_ms: false,
|
||||
offset: offset_mode == Tld4OffsetMode::AddOffI,
|
||||
mask: mask,
|
||||
})));
|
||||
} else if tex.op == nir_texop_tg4 {
|
||||
self.instrs.push(Instr::new(Op::Tld4(OpTld4 {
|
||||
dsts: dsts,
|
||||
resident: Dst::None,
|
||||
srcs: srcs,
|
||||
dim: dim,
|
||||
comp: tex.component().try_into().unwrap(),
|
||||
offset_mode: offset_mode,
|
||||
z_cmpr: flags.has_z_cmpr(),
|
||||
mask: mask,
|
||||
})));
|
||||
} else {
|
||||
assert!(offset_mode != Tld4OffsetMode::PerPx);
|
||||
self.instrs.push(Instr::new(Op::Tex(OpTex {
|
||||
dsts: dsts,
|
||||
resident: Dst::None,
|
||||
srcs: srcs,
|
||||
dim: dim,
|
||||
lod_mode: lod_mode,
|
||||
z_cmpr: flags.has_z_cmpr(),
|
||||
offset: offset_mode == Tld4OffsetMode::AddOffI,
|
||||
mask: mask,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
let mut dst_comps = Vec::new();
|
||||
for dst in dsts {
|
||||
if let Dst::SSA(dst) = dst {
|
||||
for comp in self.split(dst) {
|
||||
dst_comps.push(comp.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
for c in 0..tex.def.num_components() {
|
||||
if mask & (1 << c) == 0 {
|
||||
dst_comps.insert(c.into(), SrcRef::Zero.into());
|
||||
}
|
||||
}
|
||||
self.instrs
|
||||
.push(Instr::new_vec(self.get_dst(&tex.def), &dst_comps));
|
||||
}
|
||||
|
||||
fn parse_intrinsic(&mut self, intrin: &nir_intrinsic_instr) {
|
||||
|
|
|
|||
|
|
@ -859,6 +859,88 @@ impl fmt::Display for FRndMode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub enum TexDim {
|
||||
_1D,
|
||||
Array1D,
|
||||
_2D,
|
||||
Array2D,
|
||||
_3D,
|
||||
Cube,
|
||||
ArrayCube,
|
||||
}
|
||||
|
||||
impl fmt::Display for TexDim {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
TexDim::_1D => write!(f, "1D"),
|
||||
TexDim::Array1D => write!(f, "ARRAY_1D"),
|
||||
TexDim::_2D => write!(f, "2D"),
|
||||
TexDim::Array2D => write!(f, "ARRAY_2D"),
|
||||
TexDim::_3D => write!(f, "3D"),
|
||||
TexDim::Cube => write!(f, "CUBE"),
|
||||
TexDim::ArrayCube => write!(f, "ARRAY_CUBE"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub enum TexLodMode {
|
||||
Auto,
|
||||
Zero,
|
||||
Bias,
|
||||
Lod,
|
||||
Clamp,
|
||||
BiasClamp,
|
||||
}
|
||||
|
||||
impl fmt::Display for TexLodMode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
TexLodMode::Auto => write!(f, "LA"),
|
||||
TexLodMode::Zero => write!(f, "LZ"),
|
||||
TexLodMode::Bias => write!(f, "LB"),
|
||||
TexLodMode::Lod => write!(f, "LL"),
|
||||
TexLodMode::Clamp => write!(f, "LC"),
|
||||
TexLodMode::BiasClamp => write!(f, "LB.LC"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Tld4OffsetMode {
|
||||
None,
|
||||
AddOffI,
|
||||
PerPx,
|
||||
}
|
||||
|
||||
impl fmt::Display for Tld4OffsetMode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Tld4OffsetMode::None => write!(f, "NO_OFF"),
|
||||
Tld4OffsetMode::AddOffI => write!(f, "AOFFI"),
|
||||
Tld4OffsetMode::PerPx => write!(f, "PTP"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub enum TexQuery {
|
||||
Dimension,
|
||||
TextureType,
|
||||
SamplerPos,
|
||||
}
|
||||
|
||||
impl fmt::Display for TexQuery {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
TexQuery::Dimension => write!(f, "DIMENSION"),
|
||||
TexQuery::TextureType => write!(f, "TEXTURE_TYPE"),
|
||||
TexQuery::SamplerPos => write!(f, "SAMPLER_POS"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum IntType {
|
||||
U8,
|
||||
I8,
|
||||
|
|
@ -1501,6 +1583,182 @@ impl fmt::Display for OpPLop3 {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpTex {
|
||||
pub dsts: [Dst; 2],
|
||||
pub resident: Dst,
|
||||
pub srcs: [Src; 2],
|
||||
pub dim: TexDim,
|
||||
pub lod_mode: TexLodMode,
|
||||
pub z_cmpr: bool,
|
||||
pub offset: bool,
|
||||
pub mask: u8,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpTex {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "TEX.B")?;
|
||||
if self.lod_mode != TexLodMode::Auto {
|
||||
write!(f, ".{}", self.lod_mode)?;
|
||||
}
|
||||
if self.offset {
|
||||
write!(f, ".AOFFI")?;
|
||||
}
|
||||
if self.z_cmpr {
|
||||
write!(f, ".DC")?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
" {{ {}, {}, {} }} {{ {}, {} }} {}",
|
||||
self.dsts[0],
|
||||
self.dsts[1],
|
||||
self.resident,
|
||||
self.srcs[0],
|
||||
self.srcs[1],
|
||||
self.dim,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpTld {
|
||||
pub dsts: [Dst; 2],
|
||||
pub resident: Dst,
|
||||
pub srcs: [Src; 2],
|
||||
pub dim: TexDim,
|
||||
pub is_ms: bool,
|
||||
pub lod_mode: TexLodMode,
|
||||
pub offset: bool,
|
||||
pub mask: u8,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpTld {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "TLD.B")?;
|
||||
if self.lod_mode != TexLodMode::Auto {
|
||||
write!(f, ".{}", self.lod_mode)?;
|
||||
}
|
||||
if self.offset {
|
||||
write!(f, ".AOFFI")?;
|
||||
}
|
||||
if self.is_ms {
|
||||
write!(f, ".MS")?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
" {{ {}, {}, {} }} {{ {}, {} }} {}",
|
||||
self.dsts[0],
|
||||
self.dsts[1],
|
||||
self.resident,
|
||||
self.srcs[0],
|
||||
self.srcs[1],
|
||||
self.dim,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpTld4 {
|
||||
pub dsts: [Dst; 2],
|
||||
pub resident: Dst,
|
||||
pub srcs: [Src; 2],
|
||||
pub dim: TexDim,
|
||||
pub comp: u8,
|
||||
pub offset_mode: Tld4OffsetMode,
|
||||
pub z_cmpr: bool,
|
||||
pub mask: u8,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpTld4 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "TLD4.G.B")?;
|
||||
if self.offset_mode != Tld4OffsetMode::None {
|
||||
write!(f, ".{}", self.offset_mode)?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
" {{ {}, {}, {} }} {{ {}, {} }} {}",
|
||||
self.dsts[0],
|
||||
self.dsts[1],
|
||||
self.resident,
|
||||
self.srcs[0],
|
||||
self.srcs[1],
|
||||
self.dim,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpTmml {
|
||||
pub dsts: [Dst; 2],
|
||||
pub srcs: [Src; 2],
|
||||
pub dim: TexDim,
|
||||
pub mask: u8,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpTmml {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"TMML.B.LOD {{ {}, {} }} {{ {}, {} }} {}",
|
||||
self.dsts[0], self.dsts[1], self.srcs[0], self.srcs[1], self.dim
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpTxd {
|
||||
pub dsts: [Dst; 2],
|
||||
pub resident: Dst,
|
||||
pub srcs: [Src; 2],
|
||||
pub dim: TexDim,
|
||||
pub offset: bool,
|
||||
pub mask: u8,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpTxd {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "TXD.B")?;
|
||||
if self.offset {
|
||||
write!(f, ".AOFFI")?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
" {{ {}, {}, {} }} {{ {}, {} }} {}",
|
||||
self.dsts[0],
|
||||
self.dsts[1],
|
||||
self.resident,
|
||||
self.srcs[0],
|
||||
self.srcs[1],
|
||||
self.dim,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpTxq {
|
||||
pub dsts: [Dst; 2],
|
||||
pub src: Src,
|
||||
pub query: TexQuery,
|
||||
pub mask: u8,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpTxq {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"TXQ.B {{ {}, {} }} {} {}",
|
||||
self.dsts[0], self.dsts[1], self.src, self.query
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpLd {
|
||||
|
|
@ -1953,6 +2211,12 @@ pub enum Op {
|
|||
Mov(OpMov),
|
||||
Sel(OpSel),
|
||||
PLop3(OpPLop3),
|
||||
Tex(OpTex),
|
||||
Tld(OpTld),
|
||||
Tld4(OpTld4),
|
||||
Tmml(OpTmml),
|
||||
Txd(OpTxd),
|
||||
Txq(OpTxq),
|
||||
Ld(OpLd),
|
||||
St(OpSt),
|
||||
ALd(OpALd),
|
||||
|
|
@ -2420,6 +2684,12 @@ impl Instr {
|
|||
Op::ALd(_) => None,
|
||||
Op::ASt(_) => Some(15),
|
||||
Op::Ipa(_) => None,
|
||||
Op::Tex(_) => None,
|
||||
Op::Tld(_) => None,
|
||||
Op::Tld4(_) => None,
|
||||
Op::Tmml(_) => None,
|
||||
Op::Txd(_) => None,
|
||||
Op::Txq(_) => None,
|
||||
Op::Ld(_) => None,
|
||||
Op::St(_) => None,
|
||||
Op::Bra(_) | Op::Exit(_) => Some(15),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue