nak: Add a builder helper for OpPrmt

The builder also has some extra smarts in it for avoiding the PRMT when
the operation happens to exactly select one of the two sources.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26348>
This commit is contained in:
Faith Ekstrand 2023-11-23 21:42:57 -06:00 committed by Faith Ekstrand
parent d5693a590e
commit 7b6103ccc8
2 changed files with 27 additions and 6 deletions

View file

@ -49,6 +49,26 @@ pub trait Builder {
}
}
fn prmt_to(&mut self, dst: Dst, x: Src, y: Src, sel: [u8;4]) {
if sel == [0, 1, 2, 3] {
self.copy_to(dst, x);
} else if sel == [4, 5, 6, 7] {
self.copy_to(dst, y);
} else {
let mut sel_u32 = 0;
for i in 0..4 {
assert!(sel[i] < 16);
sel_u32 |= u32::from(sel[i]) << (i * 4);
}
self.push_op(OpPrmt {
dst: dst,
srcs: [x, y],
selection: sel_u32.into(),
});
}
}
fn copy_to(&mut self, dst: Dst, src: Src) {
self.push_op(OpCopy { dst: dst, src: src });
}
@ -206,6 +226,12 @@ pub trait SSABuilder: Builder {
dst
}
fn prmt(&mut self, x: Src, y: Src, sel: [u8;4]) -> SSARef {
let dst = self.alloc_ssa(RegFile::GPR, 1);
self.prmt_to(dst.into(), x, y, sel);
dst
}
fn sel(&mut self, cond: Src, x: Src, y: Src) -> SSARef {
assert!(cond.src_ref.is_predicate());
assert!(x.is_predicate() == y.is_predicate());

View file

@ -811,12 +811,7 @@ impl<'a> ShaderFromNir<'a> {
high: false,
});
b.push_op(OpPrmt {
dst: dst.into(),
srcs: [low.into(), high.into()],
selection: 0x5410.into(),
});
dst
b.prmt(low.into(), high.into(), [0, 1, 4, 5])
}
nir_op_u2f32 => {
assert!(alu.def.bit_size() == 32);