asahi,nir: Move asahi dynamic clipz pass to common.

Acked-by: Alyssa Rosenzweig <alyssa@rosenz.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41088>
This commit is contained in:
squidbus 2026-04-22 14:45:42 -07:00 committed by Marge Bot
parent bd62c72223
commit a41f0e62bb
5 changed files with 44 additions and 30 deletions

View file

@ -5444,6 +5444,7 @@ bool nir_lower_vars_to_scratch_global(nir_shader *shader,
bool nir_lower_scratch_to_var(nir_shader *nir);
bool nir_lower_clip_halfz(nir_shader *shader);
bool nir_lower_clip_halfz_dynamic(nir_shader *shader);
void nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint);
void nir_gather_clip_cull_distance_sizes_from_vars(nir_shader *nir);

View file

@ -2335,7 +2335,7 @@ intrinsic("quad_ballot_agx", src_comp=[1], dest_comp=1, flags=[CAN_ELIMINATE])
# 1] clipping, we need to transform z' = (z + w) / 2. We express both cases as a
# lerp between z and w, where this is the lerp coefficient: 0 for [0, 1] and 0.5
# for [-1, 1].
system_value("clip_z_coeff_agx", 1)
system_value("clip_z_coeff", 1)
# True if drawing triangle fans with first vertex provoking, false otherwise.
# This affects flatshading, which is defined weirdly for fans with first.

View file

@ -63,3 +63,42 @@ nir_lower_clip_halfz(nir_shader *shader)
nir_metadata_control_flow,
NULL);
}
/* Dynamic lowered I/O version of nir_lower_clip_halfz.
* nir_intrinsic_load_clip_z_coeff is used to load the dynamic clip coefficient.
*/
static bool
lower_pos_write_dynamic(nir_builder *b, nir_intrinsic_instr *intr,
UNUSED void *data)
{
if (intr->intrinsic != nir_intrinsic_store_output)
return false;
if (nir_intrinsic_io_semantics(intr).location != VARYING_SLOT_POS)
return false;
assert(nir_intrinsic_component(intr) == 0 && "not yet scalarized");
b->cursor = nir_before_instr(&intr->instr);
nir_def *pos = intr->src[0].ssa;
nir_def *z = nir_channel(b, pos, 2);
nir_def *w = nir_channel(b, pos, 3);
nir_def *c = nir_load_clip_z_coeff(b);
/* Lerp. If c = 0, reduces to z. If c = 1/2, reduces to (z + w)/2 */
nir_def *new_z = nir_ffma(b, nir_fneg(b, z), c, nir_ffma(b, w, c, z));
nir_src_rewrite(&intr->src[0], nir_vector_insert_imm(b, pos, new_z, 2));
return true;
}
bool
nir_lower_clip_halfz_dynamic(nir_shader *shader)
{
if (shader->info.stage != MESA_SHADER_VERTEX &&
shader->info.stage != MESA_SHADER_GEOMETRY &&
shader->info.stage != MESA_SHADER_TESS_EVAL)
return false;
return nir_shader_intrinsics_pass(shader, lower_pos_write_dynamic,
nir_metadata_control_flow,
NULL);
}

View file

@ -194,7 +194,7 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr,
return load_sysval_root(b, 1, 16, &u->sprite_mask);
case nir_intrinsic_load_shader_part_tests_zs_agx:
return load_sysval_root(b, 1, 16, &u->no_epilog_discard);
case nir_intrinsic_load_clip_z_coeff_agx:
case nir_intrinsic_load_clip_z_coeff:
return nir_f2f32(b, load_sysval_root(b, 1, 16, &u->clip_z_coeff));
case nir_intrinsic_load_rasterization_stream:
return nir_imm_int(b, 0);

View file

@ -1389,30 +1389,6 @@ asahi_cs_shader_key_equal(const void *a, const void *b)
return true;
}
/* Dynamic lowered I/O version of nir_lower_clip_halfz */
static bool
agx_nir_lower_clip_m1_1(nir_builder *b, nir_intrinsic_instr *intr,
UNUSED void *data)
{
if (intr->intrinsic != nir_intrinsic_store_output)
return false;
if (nir_intrinsic_io_semantics(intr).location != VARYING_SLOT_POS)
return false;
assert(nir_intrinsic_component(intr) == 0 && "not yet scalarized");
b->cursor = nir_before_instr(&intr->instr);
nir_def *pos = intr->src[0].ssa;
nir_def *z = nir_channel(b, pos, 2);
nir_def *w = nir_channel(b, pos, 3);
nir_def *c = nir_load_clip_z_coeff_agx(b);
/* Lerp. If c = 0, reduces to z. If c = 1/2, reduces to (z + w)/2 */
nir_def *new_z = nir_ffma(b, nir_fneg(b, z), c, nir_ffma(b, w, c, z));
nir_src_rewrite(&intr->src[0], nir_vector_insert_imm(b, pos, new_z, 2));
return true;
}
/*
* To implement point sprites, we'll replace TEX0...7 with point coordinate
* reads as required. However, the .zw needs to read back 0.0/1.0. This pass
@ -1560,8 +1536,7 @@ agx_compile_variant(struct agx_device *dev, struct pipe_context *pctx,
if (key->hw) {
NIR_PASS(_, nir, agx_nir_lower_point_size, true);
NIR_PASS(_, nir, nir_shader_intrinsics_pass, agx_nir_lower_clip_m1_1,
nir_metadata_control_flow, NULL);
NIR_PASS(_, nir, nir_lower_clip_halfz_dynamic);
NIR_PASS(_, nir, nir_lower_io_to_scalar, nir_var_shader_out, NULL,
NULL);
@ -1661,8 +1636,7 @@ agx_compile_variant(struct agx_device *dev, struct pipe_context *pctx,
*/
NIR_PASS(_, gs_copy, agx_nir_lower_point_size, false);
NIR_PASS(_, gs_copy, nir_shader_intrinsics_pass, agx_nir_lower_clip_m1_1,
nir_metadata_control_flow, NULL);
NIR_PASS(_, gs_copy, nir_lower_clip_halfz_dynamic);
NIR_PASS(_, gs_copy, nir_lower_io_to_scalar, nir_var_shader_out, NULL,
NULL);