nak: Implement f2[iu]32

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand
2023-04-10 17:23:30 -05:00
committed by Marge Bot
parent 0943da1a37
commit c2f72a5782
3 changed files with 95 additions and 1 deletions
+18
View File
@@ -618,6 +618,23 @@ impl SM75Instr {
self.set_bit(80, false /* HI */);
}
fn encode_f2i(&mut self, op: &OpF2I) {
self.encode_alu(
0x105,
Some(op.dst),
ALUSrc::None,
ALUSrc::from_src(&op.src.into()),
ALUSrc::None,
);
self.set_bit(72, op.dst_type.is_signed());
self.set_field(75..77, op.dst_type.bytes().ilog2());
self.set_bit(77, false); /* NTZ */
self.set_rnd_mode(78..80, op.rnd_mode);
self.set_bit(80, false); /* FTZ */
self.set_bit(81, false); /* DNZ */
self.set_field(84..86, op.src_type.bytes().ilog2());
}
fn encode_i2f(&mut self, op: &OpI2F) {
self.encode_alu(
0x106,
@@ -860,6 +877,7 @@ impl SM75Instr {
Op::ISetP(op) => si.encode_isetp(&op),
Op::Lop3(op) => si.encode_lop3(&op),
Op::Shl(op) => si.encode_shl(&op),
Op::F2I(op) => si.encode_f2i(&op),
Op::I2F(op) => si.encode_i2f(&op),
Op::Mov(op) => si.encode_mov(&op),
Op::Sel(op) => si.encode_sel(&op),
+12
View File
@@ -156,6 +156,18 @@ impl<'a> ShaderFromNir<'a> {
self.instrs
.push(Instr::new_sel(dst, srcs[0], srcs[1], srcs[2]));
}
nir_op_f2i32 | nir_op_f2u32 => {
let src_bits = usize::from(alu.get_src(0).bit_size());
let dst_bits = usize::from(alu.def.bit_size());
let dst_is_signed = alu.info().output_type & 2 != 0;
self.instrs.push(Instr::new(Op::F2I(OpF2I {
dst: dst,
src: srcs[0],
src_type: FloatType::from_bytes(src_bits / 8),
dst_type: IntType::from_bytes(dst_bits / 8, dst_is_signed),
rnd_mode: FRndMode::Zero,
})));
}
nir_op_fabs => {
self.instrs.push(Instr::new(Op::FMov(OpFMov {
dst: dst,
+65 -1
View File
@@ -812,6 +812,15 @@ pub enum FloatType {
}
impl FloatType {
pub fn from_bytes(bytes: usize) -> FloatType {
match bytes {
2 => FloatType::F16,
4 => FloatType::F32,
8 => FloatType::F64,
_ => panic!("Invalid float type size"),
}
}
pub fn bytes(&self) -> usize {
match self {
FloatType::F16 => 2,
@@ -862,6 +871,40 @@ pub enum IntType {
}
impl IntType {
pub fn from_bytes(bytes: usize, is_signed: bool) -> IntType {
match bytes {
1 => {
if is_signed {
IntType::I8
} else {
IntType::U8
}
}
2 => {
if is_signed {
IntType::I16
} else {
IntType::U16
}
}
4 => {
if is_signed {
IntType::I32
} else {
IntType::U32
}
}
8 => {
if is_signed {
IntType::I64
} else {
IntType::U64
}
}
_ => panic!("Invalid integer type size"),
}
}
pub fn is_signed(&self) -> bool {
match self {
IntType::U8 | IntType::U16 | IntType::U32 | IntType::U64 => false,
@@ -1277,6 +1320,26 @@ impl fmt::Display for OpShl {
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpF2I {
pub dst: Dst,
pub src: Src,
pub src_type: FloatType,
pub dst_type: IntType,
pub rnd_mode: FRndMode,
}
impl fmt::Display for OpF2I {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"F2I.{}.{}.{} {} {}",
self.dst_type, self.src_type, self.rnd_mode, self.dst, self.src,
)
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpI2F {
@@ -1801,6 +1864,7 @@ pub enum Op {
ISetP(OpISetP),
Lop3(OpLop3),
Shl(OpShl),
F2I(OpF2I),
I2F(OpI2F),
Mov(OpMov),
Sel(OpSel),
@@ -2269,7 +2333,7 @@ impl Instr {
| Op::PLop3(_)
| Op::ISetP(_)
| Op::Shl(_) => Some(6),
Op::I2F(_) | Op::Mov(_) => Some(15),
Op::F2I(_) | Op::I2F(_) | Op::Mov(_) => Some(15),
Op::MuFu(_) => None,
Op::Sel(_) => Some(15),
Op::S2R(_) => None,