asahi: use NIR gathered interpolation

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36501>
This commit is contained in:
Alyssa Rosenzweig 2025-07-31 14:49:17 -04:00 committed by Marge Bot
parent e8ff9eb9cb
commit 8b5c800d1f
5 changed files with 12 additions and 42 deletions

View file

@ -3320,38 +3320,6 @@ gather_texcoords(nir_builder *b, nir_instr *instr, void *data)
return false;
}
static bool
gather_interp(nir_builder *b, nir_intrinsic_instr *intr, void *data)
{
struct agx_interp_info *masks = data;
if (intr->intrinsic == nir_intrinsic_load_input) {
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
masks->flat |= BITFIELD64_RANGE(sem.location, sem.num_slots);
} else if (intr->intrinsic == nir_intrinsic_load_interpolated_input &&
nir_intrinsic_interp_mode(nir_src_as_intrinsic(intr->src[0])) ==
INTERP_MODE_NOPERSPECTIVE) {
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
masks->linear |= BITFIELD64_RANGE(sem.location, sem.num_slots);
}
return false;
}
/*
* Build a bit mask of varyings (by location) that are flatshaded and linear
* shaded. This information is needed by the driver.
*/
struct agx_interp_info
agx_gather_interp_info(nir_shader *nir)
{
assert(nir->info.stage == MESA_SHADER_FRAGMENT);
struct agx_interp_info masks = {0};
nir_shader_intrinsics_pass(nir, gather_interp, nir_metadata_all, &masks);
return masks;
}
/*
* Build a bit mask of varyings (by location) that are used as texture
* coordinates. This information is needed by lower_mediump_io.

View file

@ -314,7 +314,6 @@ struct agx_shader_key {
};
};
struct agx_interp_info agx_gather_interp_info(nir_shader *nir);
uint64_t agx_gather_texcoords(nir_shader *nir);
void agx_preprocess_nir(nir_shader *nir);

View file

@ -218,13 +218,14 @@ agx_assign_uvs(struct agx_varyings_vs *varyings,
{
*varyings = (struct agx_varyings_vs){0};
/* These are always flat-shaded from the FS perspective */
/* Layer/viewport always flat-shaded, no other special varyings are */
flat_mask &= BITFIELD64_RANGE(VARYING_SLOT_VAR0, 32);
flat_mask |= VARYING_BIT_LAYER | VARYING_BIT_VIEWPORT;
/* The internal cull distance slots are always linearly-interpolated */
linear_mask |= BITFIELD64_RANGE(VARYING_SLOT_CULL_PRIMITIVE, 2);
assert(!(flat_mask & linear_mask));
assert(!(flat_mask & linear_mask & layout->written));
/* TODO: Link FP16 varyings */
unsigned num_32_smooth = 0, num_32_flat = 0, num_32_linear = 0;

View file

@ -1076,8 +1076,10 @@ hk_compile_nir(struct hk_device *dev, const VkAllocationCallbacks *pAllocator,
BITSET_LAST_BIT(shader->info.vs.attrib_components_read), 4);
kill_psiz = key->vs.kill_psiz;
} else if (sw_stage == MESA_SHADER_FRAGMENT) {
shader->info.fs.interp = agx_gather_interp_info(nir);
shader->info.fs.writes_memory = nir->info.writes_memory;
shader->info.fs.interp.linear = nir->info.linear_varyings;
shader->info.fs.interp.flat =
~(nir->info.linear_varyings | nir->info.perspective_varyings);
/* Discards must be lowering before lowering MSAA to handle discards */
NIR_PASS(_, nir, agx_nir_lower_discard_zs_emit);

View file

@ -1798,7 +1798,11 @@ agx_shader_initialize(struct agx_device *dev, struct agx_uncompiled_shader *so,
nir_lower_io_use_interpolated_input_intrinsics);
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
struct agx_interp_info interp = agx_gather_interp_info(nir);
so->info.uses_fbfetch = nir->info.fs.uses_fbfetch_output;
so->info.inputs_linear_shaded = nir->info.linear_varyings;
so->info.inputs_flat_shaded = nir->info.inputs_read &
~nir->info.linear_varyings &
~nir->info.perspective_varyings;
/* Interpolate varyings at fp16 and write to the tilebuffer at fp16. As an
* exception, interpolate flat shaded at fp32. This works around a
@ -1810,12 +1814,8 @@ agx_shader_initialize(struct agx_device *dev, struct agx_uncompiled_shader *so,
NIR_PASS(_, nir, nir_lower_mediump_io,
nir_var_shader_in | nir_var_shader_out,
~(interp.flat | texcoord), false);
~(so->info.inputs_flat_shaded | texcoord), false);
}
so->info.inputs_flat_shaded = interp.flat;
so->info.inputs_linear_shaded = interp.linear;
so->info.uses_fbfetch = nir->info.fs.uses_fbfetch_output;
} else if (nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL) {
so->info.has_edgeflags = nir->info.outputs_written & VARYING_BIT_EDGE;