nak: Handle interpolate_at_offset

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-09-15 17:26:22 -05:00 committed by Marge Bot
parent f5c41151f2
commit 543eebb272
3 changed files with 36 additions and 2 deletions

View file

@ -1248,6 +1248,7 @@ impl<'a> ShaderFromNir<'a> {
});
self.set_dst(&intrin.def, dst);
}
nir_intrinsic_load_barycentric_at_offset_nv => (),
nir_intrinsic_load_barycentric_centroid => (),
nir_intrinsic_load_barycentric_pixel => (),
nir_intrinsic_load_barycentric_sample => (),
@ -1326,6 +1327,9 @@ impl<'a> ShaderFromNir<'a> {
let addr = u16::try_from(intrin.base()).unwrap()
+ u16::try_from(srcs[1].as_uint().unwrap()).unwrap();
let (freq, loc) = match bary.intrinsic {
nir_intrinsic_load_barycentric_at_offset_nv => {
(InterpFreq::Pass, InterpLoc::Offset)
},
nir_intrinsic_load_barycentric_centroid => {
(InterpFreq::Pass, InterpLoc::Centroid)
}
@ -1338,6 +1342,18 @@ impl<'a> ShaderFromNir<'a> {
_ => panic!("Unsupported interp mode"),
};
let offset = match bary.intrinsic {
nir_intrinsic_load_barycentric_at_offset_nv => {
self.get_src(&bary.get_src(0))
}
nir_intrinsic_load_barycentric_centroid
| nir_intrinsic_load_barycentric_pixel
| nir_intrinsic_load_barycentric_sample => {
Src::new_zero()
}
_ => panic!("Unsupported interp mode"),
};
assert!(intrin.def.bit_size() == 32);
let dst =
b.alloc_ssa(RegFile::GPR, intrin.def.num_components());
@ -1348,7 +1364,7 @@ impl<'a> ShaderFromNir<'a> {
addr: addr + 4 * u16::from(c),
freq: freq,
loc: loc,
offset: SrcRef::Zero.into(),
offset: offset,
});
}
self.set_dst(&intrin.def, dst);

View file

@ -3313,7 +3313,7 @@ impl fmt::Display for OpIpa {
}
write!(f, " {} a[{:#x}]", self.dst, self.addr)?;
if !self.offset.is_zero() {
if self.loc == InterpLoc::Offset {
write!(f, " {}", self.offset)?;
}
Ok(())

View file

@ -323,6 +323,24 @@ lower_fs_input_intrin(struct nir_builder *b,
UNUSED void *data)
{
switch (intrin->intrinsic) {
case nir_intrinsic_load_barycentric_at_offset: {
b->cursor = nir_before_instr(&intrin->instr);
nir_def *offset_f = intrin->src[0].ssa;
offset_f = nir_fclamp(b, offset_f, nir_imm_float(b, -0.5),
nir_imm_float(b, 0.437500));
nir_def *offset_fixed =
nir_f2i32(b, nir_fmul_imm(b, offset_f, 4096.0));
nir_def *offset_packed =
nir_ior(b, nir_ishl_imm(b, nir_channel(b, offset_fixed, 1), 16),
nir_iand_imm(b, nir_channel(b, offset_fixed, 0), 0xffff));
intrin->intrinsic = nir_intrinsic_load_barycentric_at_offset_nv;
nir_src_rewrite(&intrin->src[0], offset_packed);
return true;
}
case nir_intrinsic_load_interpolated_input: {
nir_intrinsic_instr *bary = nir_src_as_intrinsic(intrin->src[0]);
if (nir_intrinsic_interp_mode(bary) != INTERP_MODE_SMOOTH &&