nvk: nak: Add OpViLd support

Kepler and earlier GPUs do not support the ISBERD instruction but have a
different VILD (Vertex Indirect Load) instruction that provides less
functionality.  This commit adds support for the op in nak and nir,
needed for the upcoming encoder commit.

Signed-off-by: Lorenzo Rossi <snowycoder@gmail.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34329>
This commit is contained in:
Lorenzo Rossi
2025-05-07 17:31:11 +02:00
committed by Marge Bot
parent 2d48b2cb47
commit ee4cff7603
6 changed files with 64 additions and 7 deletions
@@ -904,6 +904,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
case nir_intrinsic_cmat_muladd_amd:
case nir_intrinsic_dpas_intel:
case nir_intrinsic_isberd_nv:
case nir_intrinsic_vild_nv:
case nir_intrinsic_al2p_nv:
case nir_intrinsic_ald_nv:
case nir_intrinsic_ipa_nv:
+2
View File
@@ -2459,6 +2459,8 @@ intrinsic("load_sysval_nv", dest_comp=1, src_comp=[], bit_sizes=[32, 64],
indices=[ACCESS, BASE], flags=[CAN_ELIMINATE])
intrinsic("isberd_nv", dest_comp=1, src_comp=[1], bit_sizes=[32],
flags=[CAN_ELIMINATE, CAN_REORDER])
intrinsic("vild_nv", dest_comp=1, src_comp=[1], bit_sizes=[32],
flags=[CAN_ELIMINATE, CAN_REORDER])
intrinsic("al2p_nv", dest_comp=1, src_comp=[1], bit_sizes=[32],
indices=[BASE, FLAGS], flags=[CAN_ELIMINATE, CAN_REORDER])
# src[] = { vtx, offset }.
+11
View File
@@ -2835,6 +2835,17 @@ impl<'a> ShaderFromNir<'a> {
});
self.set_dst(&intrin.def, dst.into());
}
nir_intrinsic_vild_nv => {
let dst = b.alloc_ssa(RegFile::GPR);
let (idx, off) = self.get_io_addr_offset(&srcs[0], 8);
b.push_op(OpViLd {
dst: dst.into(),
idx,
off: off.try_into().unwrap(),
});
self.set_dst(&intrin.def, dst.into());
}
nir_intrinsic_load_barycentric_at_offset_nv => (),
nir_intrinsic_load_barycentric_centroid => (),
nir_intrinsic_load_barycentric_pixel => (),
+37
View File
@@ -5741,6 +5741,41 @@ impl DisplayOp for OpIsberd {
}
impl_display_for_op!(OpIsberd);
/// Vertex Index Load
/// (Only available in Kepler)
///
/// Takes as input the vertex index and loads the vertex address in
/// attribute space.
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpViLd {
#[dst_type(GPR)]
pub dst: Dst,
#[src_type(SSA)]
pub idx: Src,
pub off: i8,
}
impl DisplayOp for OpViLd {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "vild v[")?;
if !self.idx.is_zero() {
write!(f, "{}", self.idx)?;
if self.off != 0 {
write!(f, "{:+}", self.off)?;
}
} else {
write!(f, "{}", self.off)?;
}
write!(f, "]")
}
}
impl_display_for_op!(OpViLd);
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpKill {}
@@ -6433,6 +6468,7 @@ pub enum Op {
TexDepBar(OpTexDepBar),
CS2R(OpCS2R),
Isberd(OpIsberd),
ViLd(OpViLd),
Kill(OpKill),
Nop(OpNop),
PixLd(OpPixLd),
@@ -6602,6 +6638,7 @@ impl Op {
| Op::TexDepBar(_)
| Op::CS2R(_)
| Op::Isberd(_)
| Op::ViLd(_)
| Op::Kill(_)
| Op::PixLd(_)
| Op::S2R(_) => false,
@@ -198,6 +198,7 @@ pub fn side_effect_type(op: &Op) -> SideEffect {
| Op::TexDepBar(_)
| Op::CS2R(_)
| Op::Isberd(_)
| Op::ViLd(_)
| Op::Kill(_)
| Op::S2R(_) => SideEffect::Barrier,
Op::PixLd(_) | Op::Nop(_) | Op::Vote(_) => SideEffect::None,
@@ -289,6 +290,7 @@ pub fn estimate_variable_latency(sm: u8, op: &Op) -> u32 {
| Op::TexDepBar(_)
| Op::CS2R(_)
| Op::Isberd(_)
| Op::ViLd(_)
| Op::Kill(_)
| Op::PixLd(_)
| Op::S2R(_) => 16,
+11 -7
View File
@@ -138,13 +138,17 @@ lower_vtg_io_intrin(nir_builder *b,
mask = nir_component_mask(intrin->num_components);
if (vtx != NULL && !is_output) {
nir_def *info = nir_load_sysval_nv(b, 32,
.base = NAK_SV_INVOCATION_INFO,
.access = ACCESS_CAN_REORDER);
nir_def *lo = nir_extract_u8_imm(b, info, 0);
nir_def *hi = nir_extract_u8_imm(b, info, 2);
nir_def *idx = nir_iadd(b, nir_imul(b, lo, hi), vtx);
vtx = nir_isberd_nv(b, idx);
if (nak->sm >= 50) {
nir_def *info = nir_load_sysval_nv(b, 32,
.base = NAK_SV_INVOCATION_INFO,
.access = ACCESS_CAN_REORDER);
nir_def *lo = nir_extract_u8_imm(b, info, 0);
nir_def *hi = nir_extract_u8_imm(b, info, 2);
nir_def *idx = nir_iadd(b, nir_imul(b, lo, hi), vtx);
vtx = nir_isberd_nv(b, idx);
} else {
vtx = nir_vild_nv(b, vtx);
}
}
if (vtx == NULL)