diff --git a/src/nouveau/compiler/nak_from_nir.rs b/src/nouveau/compiler/nak_from_nir.rs index 2c7f5b924d3..beba48b7564 100644 --- a/src/nouveau/compiler/nak_from_nir.rs +++ b/src/nouveau/compiler/nak_from_nir.rs @@ -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); diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs index 3975b8817ae..ade147fa0fe 100644 --- a/src/nouveau/compiler/nak_ir.rs +++ b/src/nouveau/compiler/nak_ir.rs @@ -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(()) diff --git a/src/nouveau/compiler/nak_nir.c b/src/nouveau/compiler/nak_nir.c index 0cd1a59b967..858c81a67ab 100644 --- a/src/nouveau/compiler/nak_nir.c +++ b/src/nouveau/compiler/nak_nir.c @@ -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 &&