From ebe91b02c47e5764039cdf075aef73ca00167301 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Thu, 28 May 2026 23:18:15 -0400 Subject: [PATCH] kraid: Implement nir_op_u2u/i2i Part-of: --- src/panfrost/compiler/kraid/nir.rs | 82 ++++++++++++++++++++++++++++++ src/panfrost/compiler/kraid/ops.rs | 2 +- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/panfrost/compiler/kraid/nir.rs b/src/panfrost/compiler/kraid/nir.rs index f85c387c596..f8ab6b3e0a2 100644 --- a/src/panfrost/compiler/kraid/nir.rs +++ b/src/panfrost/compiler/kraid/nir.rs @@ -349,6 +349,47 @@ impl<'a> ShaderFromNir<'a> { accum_op: CmpAccumOp::None, }); } + nir_op_i2i8 | nir_op_i2i16 | nir_op_i2i32 => { + let dst_bits = alu.def.bit_size; + let src_bits = alu.get_src(0).bit_size(); + let swz = match (dst_bits, src_bits) { + (8, 8) => Swizzle::NONE, + (8, 16) => Swizzle::from_bytes([0, 2, 0, 2]), + (8, 32) => Swizzle::replicate_byte(0), + (16, 8) => Swizzle::widen_v2s8(0, 1), + (16, 16) => Swizzle::NONE, + (16, 32) => Swizzle::replicate_half(0), + (32, 8) => Swizzle::widen_s8(0), + (32, 16) => Swizzle::widen_s16(0), + (32, 32) => Swizzle::NONE, + (d, s) => panic!("u{s}_to_u{d} unsupported"), + }; + if dst_bits == 8 { + // We don't have IADD.v4i8 but that's okay because + // 8-bit destinations don't need us to widen. + b.push_op(OpShiftLop { + dst: dst.into(), + dst_type: dst_type(NumericType::Integer), + shift_op: ShiftOp::LShift, + logic_op: LogicOp::Or, + not_result: false, + src0: srcs(0).swizzle(swz), + shift: 0.into(), + src2: 0.into(), + }); + } else { + b.push_op(OpIAdd { + dst: dst.into(), + dst_type: dst_type(if dst_bits > src_bits { + NumericType::SignedInteger + } else { + NumericType::Integer + }), + saturate: false, + srcs: [srcs(0).swizzle(swz), 0.into()], + }); + } + } nir_op_iadd => { b.push_op(OpIAdd { dst: dst.into(), @@ -438,6 +479,47 @@ impl<'a> ShaderFromNir<'a> { src2: 0.into(), }); } + nir_op_u2u8 | nir_op_u2u16 | nir_op_u2u32 => { + let dst_bits = alu.def.bit_size; + let src_bits = alu.get_src(0).bit_size(); + let swz = match (dst_bits, src_bits) { + (8, 8) => Swizzle::NONE, + (8, 16) => Swizzle::from_bytes([0, 2, 0, 2]), + (8, 32) => Swizzle::replicate_byte(0), + (16, 8) => Swizzle::widen_v2u8(0, 1), + (16, 16) => Swizzle::NONE, + (16, 32) => Swizzle::replicate_half(0), + (32, 8) => Swizzle::widen_u8(0), + (32, 16) => Swizzle::widen_u16(0), + (32, 32) => Swizzle::NONE, + (d, s) => panic!("u{s}_to_u{d} unsupported"), + }; + if dst_bits == 8 { + // We don't have IADD.v4i8 but that's okay because + // 8-bit destinations don't need us to widen. + b.push_op(OpShiftLop { + dst: dst.into(), + dst_type: dst_type(NumericType::Integer), + shift_op: ShiftOp::LShift, + logic_op: LogicOp::Or, + not_result: false, + src0: srcs(0).swizzle(swz), + shift: 0.into(), + src2: 0.into(), + }); + } else { + b.push_op(OpIAdd { + dst: dst.into(), + dst_type: dst_type(if dst_bits > src_bits { + NumericType::UnsignedInteger + } else { + NumericType::Integer + }), + saturate: false, + srcs: [srcs(0).swizzle(swz), 0.into()], + }); + } + } _ => panic!("Unsupported ALU instruction: {}", alu.info().name()), } } diff --git a/src/panfrost/compiler/kraid/ops.rs b/src/panfrost/compiler/kraid/ops.rs index a491ece6cc7..ae906e9d6f0 100644 --- a/src/panfrost/compiler/kraid/ops.rs +++ b/src/panfrost/compiler/kraid/ops.rs @@ -475,7 +475,7 @@ impl fmt::Display for LogicOp { #[repr(C)] #[derive(Clone, Opcode)] -#[variants(dst_type in [V4I8, V2I16, I32, I64])] +#[variants(dst_type in [I8, I16, V4I8, V2I16, I32, I64])] pub struct OpShiftLop { pub dst: Dst, pub dst_type: DataType,