nir: Add isbewr_nv intrinsic and extends isberd_nv

Adds a new intrinsic allowing to do raw write in the various ISBE spaces
where attributes are stored.

This also adapt isberd_nv to map to what we have since SM70+.

This will be used to support mesh shaders.

Signed-off-by: Mary Guillemard <mary@mary.zone>
Reviewed-by: Mel Henning <mhenning@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39716>
This commit is contained in:
Mary Guillemard 2026-02-05 09:21:26 +01:00 committed by Marge Bot
parent 796e1749c6
commit 6a8d09972e
5 changed files with 49 additions and 3 deletions

View file

@ -994,6 +994,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
case nir_intrinsic_dpas_intel:
case nir_intrinsic_convert_cmat_intel:
case nir_intrinsic_isberd_nv:
case nir_intrinsic_isbewr_nv:
case nir_intrinsic_vild_nv:
case nir_intrinsic_al2p_nv:
case nir_intrinsic_ald_nv:

View file

@ -2768,8 +2768,15 @@ intrinsic("ldcx_nv", dest_comp=0, src_comp=[1, 1],
flags=[CAN_ELIMINATE, CAN_REORDER])
intrinsic("load_sysval_nv", dest_comp=1, src_comp=[], bit_sizes=[32, 64],
indices=[ACCESS, BASE, DIVERGENT], flags=[CAN_ELIMINATE])
intrinsic("isberd_nv", dest_comp=1, src_comp=[1], bit_sizes=[32],
flags=[CAN_ELIMINATE, CAN_REORDER])
# src[] = { offset }.
# FLAGS is struct nak_nir_isbe_flags
intrinsic("isberd_nv", dest_comp=1, src_comp=[1], bit_sizes=[8, 16, 32],
indices=[RANGE_BASE, RANGE, FLAGS, ACCESS],
flags=[CAN_ELIMINATE])
# src[] = { data, offset }.
# FLAGS is struct nak_nir_isbe_flags
intrinsic("isbewr_nv", src_comp=[0, 1],
indices=[RANGE_BASE, RANGE, FLAGS, ACCESS], flags=[])
intrinsic("vild_nv", dest_comp=1, src_comp=[1], bit_sizes=[32],
flags=[CAN_ELIMINATE, CAN_REORDER],
indices=[BASE])

View file

@ -3033,6 +3033,19 @@ impl<'a> ShaderFromNir<'a> {
self.set_dst(&intrin.def, dst.into());
}
nir_intrinsic_isberd_nv => {
let flags = intrin.flags();
let flags: nak_nir_isbe_flags =
unsafe { std::mem::transmute_copy(&flags) };
// TODO: Implement 16 and 32 bits in ISBERD
assert!(
intrin.def.bit_size() == 8
&& intrin.def.num_components == 1
);
// TODO: Implement mode in ISBERD
assert!(flags.mode() == NAK_ISBE_MODE_MAP);
let dst = b.alloc_ssa(RegFile::GPR);
b.push_op(OpIsberd {
dst: dst.into(),

View file

@ -144,7 +144,17 @@ lower_vtg_io_intrin(nir_builder *b,
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);
const struct nak_nir_isbe_flags flags = {
.mode = NAK_ISBE_MODE_MAP,
.output = false,
.skew = false,
.per_primitive = false,
};
vtx = nir_isberd_nv(b, 8, idx,
.flags = NAK_AS_U32(flags),
.access = ACCESS_CAN_REORDER);
} else {
vtx = nir_vild_nv(b, vtx);
}

View file

@ -257,6 +257,21 @@ struct nak_nir_imadsp_flags {
bool nak_nir_lower_vtg_io(nir_shader *nir, const struct nak_compiler *nak);
enum nak_isbe_mode {
NAK_ISBE_MODE_MAP,
NAK_ISBE_MODE_PATCH,
NAK_ISBE_MODE_PRIM,
NAK_ISBE_MODE_ATTR,
};
struct nak_nir_isbe_flags {
enum nak_isbe_mode mode : 2;
bool output : 1;
bool skew : 1;
bool per_primitive : 1;
uint32_t pad : 27;
};
enum nak_interp_mode {
NAK_INTERP_MODE_PERSPECTIVE,
NAK_INTERP_MODE_SCREEN_LINEAR,