nak: Implement MuFu and a bunch of float unops

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-04-10 17:23:29 -05:00 committed by Marge Bot
parent f9f9399773
commit 88f7056d09
3 changed files with 106 additions and 0 deletions

View file

@ -466,6 +466,31 @@ impl SM75Instr {
self.set_bit(90, false); /* TODO: src pred neg */
}
fn encode_mufu(&mut self, op: &OpMuFu) {
self.encode_alu(
0x108,
Some(op.dst),
ALUSrc::None,
ALUSrc::from_src(&op.src),
ALUSrc::None,
);
self.set_field(
74..80,
match op.op {
MuFuOp::Cos => 0,
MuFuOp::Sin => 1,
MuFuOp::Exp2 => 2,
MuFuOp::Log2 => 3,
MuFuOp::Rcp => 4,
MuFuOp::Rsq => 5,
MuFuOp::Rcp64H => 6,
MuFuOp::Rsq64H => 7,
MuFuOp::Sqrt => 8,
MuFuOp::Tanh => 9,
},
);
}
fn encode_iadd3(&mut self, op: &OpIAdd3) {
/* TODO: This should happen as part of a legalization pass */
assert!(op.srcs[0].is_reg_or_zero());
@ -798,6 +823,7 @@ impl SM75Instr {
Op::FMul(op) => si.encode_fmul(&op),
Op::FSet(op) => si.encode_fset(&op),
Op::FSetP(op) => si.encode_fsetp(&op),
Op::MuFu(op) => si.encode_mufu(&op),
Op::IAdd3(op) => si.encode_iadd3(&op),
Op::IMnMx(op) => si.encode_imnmx(&op),
Op::ISetP(op) => si.encode_isetp(&op),

View file

@ -146,6 +146,9 @@ impl<'a> ShaderFromNir<'a> {
nir_op_fadd => {
self.instrs.push(Instr::new_fadd(dst, srcs[0], srcs[1]));
}
nir_op_fcos => {
self.instrs.push(Instr::new_mufu(dst, MuFuOp::Cos, srcs[0]));
}
nir_op_feq => {
self.instrs.push(Instr::new_fsetp(
dst,
@ -154,6 +157,10 @@ impl<'a> ShaderFromNir<'a> {
srcs[1],
));
}
nir_op_fexp2 => {
self.instrs
.push(Instr::new_mufu(dst, MuFuOp::Exp2, srcs[0]));
}
nir_op_fge => {
self.instrs.push(Instr::new_fsetp(
dst,
@ -162,6 +169,10 @@ impl<'a> ShaderFromNir<'a> {
srcs[1],
));
}
nir_op_flog2 => {
self.instrs
.push(Instr::new_mufu(dst, MuFuOp::Log2, srcs[0]));
}
nir_op_flt => {
self.instrs.push(Instr::new_fsetp(
dst,
@ -202,6 +213,12 @@ impl<'a> ShaderFromNir<'a> {
saturate: false,
})));
}
nir_op_frcp => {
self.instrs.push(Instr::new_mufu(dst, MuFuOp::Rcp, srcs[0]));
}
nir_op_frsq => {
self.instrs.push(Instr::new_mufu(dst, MuFuOp::Rsq, srcs[0]));
}
nir_op_fsat => {
self.instrs.push(Instr::new(Op::FMov(OpFMov {
dst: dst,
@ -232,6 +249,13 @@ impl<'a> ShaderFromNir<'a> {
Src::from(lz).neg(),
));
}
nir_op_fsin => {
self.instrs.push(Instr::new_mufu(dst, MuFuOp::Sin, srcs[0]));
}
nir_op_fsqrt => {
self.instrs
.push(Instr::new_mufu(dst, MuFuOp::Sqrt, srcs[0]));
}
nir_op_i2f32 => {
self.instrs.push(Instr::new_i2f(dst, srcs[0]));
}

View file

@ -1118,6 +1118,51 @@ impl fmt::Display for OpFSetP {
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum MuFuOp {
Cos,
Sin,
Exp2,
Log2,
Rcp,
Rsq,
Rcp64H,
Rsq64H,
Sqrt,
Tanh,
}
impl fmt::Display for MuFuOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MuFuOp::Cos => write!(f, "COS"),
MuFuOp::Sin => write!(f, "SIN"),
MuFuOp::Exp2 => write!(f, "EXP2"),
MuFuOp::Log2 => write!(f, "LOG2"),
MuFuOp::Rcp => write!(f, "RCP"),
MuFuOp::Rsq => write!(f, "RSQ"),
MuFuOp::Rcp64H => write!(f, "RCP64H"),
MuFuOp::Rsq64H => write!(f, "RSQ64H"),
MuFuOp::Sqrt => write!(f, "SQRT"),
MuFuOp::Tanh => write!(f, "TANH"),
}
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpMuFu {
pub dst: Dst,
pub op: MuFuOp,
pub src: Src,
}
impl fmt::Display for OpMuFu {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "MUFU.{} {} {}", self.op, self.dst, self.src)
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpIAdd3 {
@ -1702,6 +1747,7 @@ pub enum Op {
FAdd(OpFAdd),
FMnMx(OpFMnMx),
FMul(OpFMul),
MuFu(OpMuFu),
FSet(OpFSet),
FSetP(OpFSetP),
IAdd3(OpIAdd3),
@ -1933,6 +1979,14 @@ impl Instr {
}))
}
pub fn new_mufu(dst: Dst, op: MuFuOp, src: Src) -> Instr {
Instr::new(Op::MuFu(OpMuFu {
dst: dst,
op: op,
src: src,
}))
}
pub fn new_iadd(dst: Dst, x: Src, y: Src) -> Instr {
Instr::new(Op::IAdd3(OpIAdd3 {
dst: dst,
@ -2151,6 +2205,7 @@ impl Instr {
| Op::FMul(_)
| Op::FSet(_)
| Op::FSetP(_)
| Op::MuFu(_)
| Op::IAdd3(_)
| Op::IMnMx(_)
| Op::Lop3(_)
@ -2158,6 +2213,7 @@ impl Instr {
| Op::ISetP(_)
| Op::Shl(_) => Some(6),
Op::I2F(_) | Op::Mov(_) => Some(15),
Op::MuFu(_) => None,
Op::Sel(_) => Some(15),
Op::S2R(_) => None,
Op::ALd(_) => None,