nak: Add separate True and False source types
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
committed by
Marge Bot
parent
29ecb7acf1
commit
548cb292cf
@@ -331,6 +331,7 @@ pub extern "C" fn nak_compile_shader(
|
||||
|
||||
s.assign_regs_trivial();
|
||||
s.lower_vec_split();
|
||||
s.lower_mov_predicate();
|
||||
s.calc_instr_deps();
|
||||
|
||||
println!("NAK IR:\n{}", &s);
|
||||
|
||||
@@ -157,9 +157,20 @@ impl SM75Instr {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_pred_src(&mut self, range: Range<usize>, not_bit: isize, src: Src) {
|
||||
fn set_pred_src(
|
||||
&mut self,
|
||||
range: Range<usize>,
|
||||
not_bit: isize,
|
||||
src: Src,
|
||||
default: bool,
|
||||
) {
|
||||
match src.src_ref {
|
||||
SrcRef::Zero => {
|
||||
SrcRef::True => {
|
||||
assert!(default);
|
||||
self.set_pred_reg(range, RegRef::zero(RegFile::Pred, 1));
|
||||
}
|
||||
SrcRef::False => {
|
||||
assert!(!default);
|
||||
self.set_pred_reg(range, RegRef::zero(RegFile::Pred, 1));
|
||||
}
|
||||
SrcRef::Reg(reg) => self.set_pred_reg(range, reg),
|
||||
@@ -455,7 +466,7 @@ impl SM75Instr {
|
||||
}
|
||||
|
||||
self.set_pred_dst(81..84, op.overflow);
|
||||
self.set_pred_src(84..87, -1, op.carry);
|
||||
self.set_pred_src(84..87, -1, op.carry, false);
|
||||
}
|
||||
|
||||
fn set_int_cmp_op(&mut self, range: Range<usize>, op: IntCmpOp) {
|
||||
@@ -566,7 +577,7 @@ impl SM75Instr {
|
||||
ALUSrc::None,
|
||||
);
|
||||
|
||||
self.set_pred_src(87..90, 90, op.cond);
|
||||
self.set_pred_src(87..90, 90, op.cond, true);
|
||||
}
|
||||
|
||||
fn encode_plop3(&mut self, op: &OpPLop3) {
|
||||
@@ -574,13 +585,13 @@ impl SM75Instr {
|
||||
self.set_field(64..67, op.op.lut & 0x7);
|
||||
self.set_field(72..77, op.op.lut >> 3);
|
||||
|
||||
self.set_pred_src(68..71, 71, op.srcs[2]);
|
||||
self.set_pred_src(68..71, 71, op.srcs[2], true);
|
||||
|
||||
self.set_pred_src(77..80, 80, op.srcs[1]);
|
||||
self.set_pred_src(77..80, 80, op.srcs[1], true);
|
||||
self.set_pred_dst(81..84, op.dst);
|
||||
self.set_field(84..87, 7_u8); /* Def1 */
|
||||
|
||||
self.set_pred_src(87..90, 90, op.srcs[0]);
|
||||
self.set_pred_src(87..90, 90, op.srcs[0], true);
|
||||
}
|
||||
|
||||
fn set_mem_access(&mut self, access: &MemAccess) {
|
||||
|
||||
@@ -238,7 +238,7 @@ impl<'a> ShaderFromNir<'a> {
|
||||
dst: sum[0].into(),
|
||||
overflow: carry.into(),
|
||||
srcs: [x[0].into(), y[0].into(), Src::new_zero()],
|
||||
carry: Src::new_zero(),
|
||||
carry: SrcRef::False.into(),
|
||||
})));
|
||||
self.instrs.push(Instr::new(Op::IAdd3(OpIAdd3 {
|
||||
dst: sum[1].into(),
|
||||
@@ -260,7 +260,7 @@ impl<'a> ShaderFromNir<'a> {
|
||||
LogicOp::new_lut(&|x, y, _| x & y),
|
||||
srcs[0],
|
||||
srcs[1],
|
||||
Src::new_zero(),
|
||||
Src::new_imm_bool(true),
|
||||
));
|
||||
} else {
|
||||
self.instrs.push(Instr::new_lop3(
|
||||
@@ -320,8 +320,8 @@ impl<'a> ShaderFromNir<'a> {
|
||||
dst,
|
||||
LogicOp::new_lut(&|x, _, _| !x),
|
||||
srcs[0],
|
||||
Src::new_zero(),
|
||||
Src::new_zero(),
|
||||
Src::new_imm_bool(true),
|
||||
Src::new_imm_bool(true),
|
||||
));
|
||||
} else {
|
||||
self.instrs.push(Instr::new_lop3(
|
||||
@@ -340,7 +340,7 @@ impl<'a> ShaderFromNir<'a> {
|
||||
LogicOp::new_lut(&|x, y, _| x | y),
|
||||
srcs[0],
|
||||
srcs[1],
|
||||
Src::new_zero(),
|
||||
Src::new_imm_bool(true),
|
||||
));
|
||||
} else {
|
||||
self.instrs.push(Instr::new_lop3(
|
||||
@@ -508,13 +508,18 @@ impl<'a> ShaderFromNir<'a> {
|
||||
let dst = self.get_dst(&load_const.def);
|
||||
let mut srcs = Vec::new();
|
||||
for c in 0..load_const.def.num_components {
|
||||
assert!(load_const.def.bit_size == 32);
|
||||
let imm_u32 = unsafe { load_const.values()[c as usize].u32_ };
|
||||
srcs.push(if imm_u32 == 0 {
|
||||
Src::new_zero()
|
||||
if load_const.def.bit_size == 1 {
|
||||
let imm_b1 = unsafe { load_const.values()[c as usize].b };
|
||||
srcs.push(Src::new_imm_bool(imm_b1));
|
||||
} else {
|
||||
Src::new_imm_u32(imm_u32)
|
||||
});
|
||||
assert!(load_const.def.bit_size == 32);
|
||||
let imm_u32 = unsafe { load_const.values()[c as usize].u32_ };
|
||||
srcs.push(if imm_u32 == 0 {
|
||||
Src::new_zero()
|
||||
} else {
|
||||
Src::new_imm_u32(imm_u32)
|
||||
});
|
||||
}
|
||||
}
|
||||
self.instrs.push(Instr::new_vec(dst, &srcs));
|
||||
}
|
||||
|
||||
@@ -277,6 +277,8 @@ pub struct CBufRef {
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum SrcRef {
|
||||
Zero,
|
||||
True,
|
||||
False,
|
||||
Imm32(u32),
|
||||
CBuf(CBufRef),
|
||||
SSA(SSAValue),
|
||||
@@ -300,7 +302,11 @@ impl SrcRef {
|
||||
|
||||
pub fn get_reg(&self) -> Option<&RegRef> {
|
||||
match self {
|
||||
SrcRef::Zero | SrcRef::Imm32(_) | SrcRef::SSA(_) => None,
|
||||
SrcRef::Zero
|
||||
| SrcRef::True
|
||||
| SrcRef::False
|
||||
| SrcRef::Imm32(_)
|
||||
| SrcRef::SSA(_) => None,
|
||||
SrcRef::CBuf(cb) => match &cb.buf {
|
||||
CBuf::Binding(_) | CBuf::BindlessSSA(_) => None,
|
||||
CBuf::BindlessGPR(reg) => Some(reg),
|
||||
@@ -311,7 +317,11 @@ impl SrcRef {
|
||||
|
||||
pub fn get_ssa(&self) -> Option<&SSAValue> {
|
||||
match self {
|
||||
SrcRef::Zero | SrcRef::Imm32(_) | SrcRef::Reg(_) => None,
|
||||
SrcRef::Zero
|
||||
| SrcRef::True
|
||||
| SrcRef::False
|
||||
| SrcRef::Imm32(_)
|
||||
| SrcRef::Reg(_) => None,
|
||||
SrcRef::CBuf(cb) => match &cb.buf {
|
||||
CBuf::Binding(_) | CBuf::BindlessGPR(_) => None,
|
||||
CBuf::BindlessSSA(ssa) => Some(ssa),
|
||||
@@ -337,6 +347,8 @@ impl fmt::Display for SrcRef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
SrcRef::Zero => write!(f, "ZERO")?,
|
||||
SrcRef::True => write!(f, "TRUE")?,
|
||||
SrcRef::False => write!(f, "FALSE")?,
|
||||
SrcRef::Imm32(u) => write!(f, "{:#x}", u)?,
|
||||
SrcRef::CBuf(r) => {
|
||||
match r.buf {
|
||||
@@ -451,6 +463,10 @@ impl Src {
|
||||
SrcRef::Imm32(u).into()
|
||||
}
|
||||
|
||||
pub fn new_imm_bool(b: bool) -> Src {
|
||||
Src::from(if b { SrcRef::True } else { SrcRef::False })
|
||||
}
|
||||
|
||||
pub fn new_cbuf(idx: u8, offset: u16) -> Src {
|
||||
SrcRef::CBuf(CBufRef {
|
||||
buf: CBuf::Binding(idx),
|
||||
@@ -498,12 +514,25 @@ impl Src {
|
||||
|
||||
pub fn is_uniform(&self) -> bool {
|
||||
match self.src_ref {
|
||||
SrcRef::Zero | SrcRef::Imm32(_) | SrcRef::CBuf(_) => true,
|
||||
SrcRef::Zero
|
||||
| SrcRef::True
|
||||
| SrcRef::False
|
||||
| SrcRef::Imm32(_)
|
||||
| SrcRef::CBuf(_) => true,
|
||||
SrcRef::SSA(ssa) => ssa.is_uniform(),
|
||||
SrcRef::Reg(reg) => reg.is_uniform(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_predicate(&self) -> bool {
|
||||
match self.src_ref {
|
||||
SrcRef::Zero | SrcRef::Imm32(_) | SrcRef::CBuf(_) => false,
|
||||
SrcRef::True | SrcRef::False => true,
|
||||
SrcRef::SSA(ssa) => ssa.is_predicate(),
|
||||
SrcRef::Reg(reg) => reg.is_predicate(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
match self.src_ref {
|
||||
SrcRef::Zero => true,
|
||||
@@ -514,7 +543,10 @@ impl Src {
|
||||
pub fn is_reg_or_zero(&self) -> bool {
|
||||
match self.src_ref {
|
||||
SrcRef::Zero | SrcRef::SSA(_) | SrcRef::Reg(_) => true,
|
||||
SrcRef::Imm32(_) | SrcRef::CBuf(_) => false,
|
||||
SrcRef::True
|
||||
| SrcRef::False
|
||||
| SrcRef::Imm32(_)
|
||||
| SrcRef::CBuf(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -660,6 +692,12 @@ impl LogicOp {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_const(val: bool) -> LogicOp {
|
||||
LogicOp {
|
||||
lut: if val { !0 } else { 0 },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval<
|
||||
T: BitAnd<Output = T> + BitOr<Output = T> + Copy + Not<Output = T>,
|
||||
>(
|
||||
@@ -1614,7 +1652,7 @@ impl Instr {
|
||||
dst: dst,
|
||||
overflow: Dst::None,
|
||||
srcs: [Src::new_zero(), x, y],
|
||||
carry: Src::new_zero(),
|
||||
carry: Src::new_imm_bool(false),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1675,6 +1713,7 @@ impl Instr {
|
||||
}
|
||||
|
||||
pub fn new_plop3(dst: Dst, op: LogicOp, x: Src, y: Src, z: Src) -> Instr {
|
||||
assert!(x.is_predicate() && y.is_predicate() && z.is_predicate());
|
||||
Instr::new(Op::PLop3(OpPLop3 {
|
||||
dst: dst,
|
||||
srcs: [x, y, z],
|
||||
@@ -1974,7 +2013,7 @@ impl Shader {
|
||||
dst: mov.dst,
|
||||
overflow: Dst::None,
|
||||
srcs: [Src::new_zero(), mov.src, Src::new_zero()],
|
||||
carry: Src::new_zero(),
|
||||
carry: Src::new_imm_bool(false),
|
||||
}))]
|
||||
}
|
||||
Op::Vec(vec) => {
|
||||
@@ -2029,6 +2068,51 @@ impl Shader {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lower_mov_predicate(&mut self) {
|
||||
self.map_instrs(&|instr: Instr, _| -> Vec<Instr> {
|
||||
match &instr.op {
|
||||
Op::Mov(mov) => {
|
||||
assert!(mov.src.src_mod.is_none());
|
||||
match mov.src.src_ref {
|
||||
SrcRef::True => {
|
||||
vec![Instr::new_isetp(
|
||||
mov.dst,
|
||||
IntCmpType::I32,
|
||||
IntCmpOp::Eq,
|
||||
Src::new_zero(),
|
||||
Src::new_zero(),
|
||||
)]
|
||||
}
|
||||
SrcRef::False => {
|
||||
vec![Instr::new_isetp(
|
||||
mov.dst,
|
||||
IntCmpType::I32,
|
||||
IntCmpOp::Ne,
|
||||
Src::new_zero(),
|
||||
Src::new_zero(),
|
||||
)]
|
||||
}
|
||||
SrcRef::Reg(reg) => {
|
||||
if reg.is_predicate() {
|
||||
vec![Instr::new_plop3(
|
||||
mov.dst,
|
||||
LogicOp::new_lut(&|x, _, _| x),
|
||||
mov.src,
|
||||
Src::new_imm_bool(true),
|
||||
Src::new_imm_bool(true),
|
||||
)]
|
||||
} else {
|
||||
vec![instr]
|
||||
}
|
||||
}
|
||||
_ => vec![instr],
|
||||
}
|
||||
}
|
||||
_ => vec![instr],
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Shader {
|
||||
|
||||
@@ -12,7 +12,7 @@ struct LegalizeInstr<'a> {
|
||||
|
||||
fn src_is_reg(src: &Src) -> bool {
|
||||
match src.src_ref {
|
||||
SrcRef::Zero | SrcRef::SSA(_) => true,
|
||||
SrcRef::Zero | SrcRef::True | SrcRef::False | SrcRef::SSA(_) => true,
|
||||
SrcRef::Imm32(_) | SrcRef::CBuf(_) => false,
|
||||
SrcRef::Reg(_) => panic!("Not in SSA form"),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user