asahi/lib: Move alpha_to_one and alpha_to_coverage lowering to common code.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33942>
This commit is contained in:
Ella Stanforth 2025-04-08 16:27:11 +01:00 committed by Marge Bot
parent 091d52965f
commit d3aedbfe9d
12 changed files with 26 additions and 28 deletions

View file

@ -97,7 +97,7 @@ lower_discard(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data)
killed_samples = nir_bcsel(b, intr->src[0].ssa, all_samples, no_samples);
/* This will get lowered later as needed */
nir_discard_agx(b, killed_samples);
nir_demote_samples(b, killed_samples);
nir_instr_remove(&intr->instr);
return true;
}

View file

@ -65,7 +65,7 @@
* 5. zs_emit may be used in the shader exactly once to trigger tests.
* sample_mask with 0 may be used to discard early.
*
* This pass lowers discard_agx to sample_mask instructions satisfying these
* This pass lowers demote_samples to sample_mask instructions satisfying these
* rules. Other passes should not generate sample_mask instructions, as there
* are too many footguns.
*/
@ -78,7 +78,7 @@ static bool
lower_discard_to_sample_mask_0(nir_builder *b, nir_intrinsic_instr *intr,
UNUSED void *data)
{
if (intr->intrinsic != nir_intrinsic_discard_agx)
if (intr->intrinsic != nir_intrinsic_demote_samples)
return false;
b->cursor = nir_before_instr(&intr->instr);
@ -95,7 +95,7 @@ last_discard_in_block(nir_block *block)
continue;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic == nir_intrinsic_discard_agx)
if (intr->intrinsic == nir_intrinsic_demote_samples)
return intr;
}

View file

@ -27,7 +27,7 @@ lower_to_per_sample(nir_builder *b, nir_intrinsic_instr *intr, void *data)
case nir_intrinsic_load_local_pixel_agx:
case nir_intrinsic_store_local_pixel_agx:
case nir_intrinsic_store_zs_agx:
case nir_intrinsic_discard_agx:
case nir_intrinsic_demote_samples:
case nir_intrinsic_sample_mask_agx: {
/* Fragment I/O inside the loop should only affect active samples. */
unsigned mask_index =

View file

@ -175,7 +175,7 @@ lower(nir_builder *b, nir_intrinsic_instr *intr, void *data)
if (*ignore_sample_mask_without_msaa)
mask = select_if_msaa_else_0(b, mask);
nir_discard_agx(b, mask);
nir_demote_samples(b, mask);
nir_instr_remove(&intr->instr);
b->shader->info.fs.uses_discard = true;
@ -196,7 +196,7 @@ lower(nir_builder *b, nir_intrinsic_instr *intr, void *data)
* The load_sample_id intrinsics themselves are lowered later, with different
* lowerings for monolithic vs epilogs.
*
* Note that fragment I/O (like store_local_pixel_agx and discard_agx) does not
* Note that fragment I/O (like store_local_pixel_agx and demote_samples) does not
* get lowered here, because that lowering is different for monolithic vs FS
* epilogs even though there's no dependency on sample count.
*/

View file

@ -447,7 +447,7 @@ agx_nir_fs_epilog(nir_builder *b, const void *key_)
/* Alpha-to-coverage must be lowered before alpha-to-one */
if (key->blend.alpha_to_coverage)
NIR_PASS(_, b->shader, agx_nir_lower_alpha_to_coverage, tib.nr_samples);
NIR_PASS(_, b->shader, nir_lower_alpha_to_coverage, tib.nr_samples);
/* Depth/stencil writes must be deferred until after all discards,
* particularly alpha-to-coverage.
@ -468,7 +468,7 @@ agx_nir_fs_epilog(nir_builder *b, const void *key_)
/* Alpha-to-one must be lowered before blending */
if (key->blend.alpha_to_one)
NIR_PASS(_, b->shader, agx_nir_lower_alpha_to_one);
NIR_PASS(_, b->shader, nir_lower_alpha_to_one);
NIR_PASS(_, b->shader, nir_lower_blend, &opts);
@ -550,7 +550,7 @@ lower_output_to_epilog(nir_builder *b, nir_intrinsic_instr *intr, void *data)
return true;
}
if (intr->intrinsic == nir_intrinsic_discard_agx &&
if (intr->intrinsic == nir_intrinsic_demote_samples &&
b->shader->info.fs.early_fragment_tests) {
if (!ctx->masked_samples) {
@ -697,7 +697,7 @@ agx_nir_fs_prolog(nir_builder *b, const void *key_)
/* First, insert code for any emulated features */
if (key->api_sample_mask != 0xff) {
/* Kill samples that are NOT covered by the mask */
nir_discard_agx(b, nir_imm_intN_t(b, key->api_sample_mask ^ 0xff, 16));
nir_demote_samples(b, nir_imm_intN_t(b, key->api_sample_mask ^ 0xff, 16));
b->shader->info.fs.uses_discard = true;
}

View file

@ -106,11 +106,6 @@ bool agx_nir_lower_monolithic_msaa(struct nir_shader *shader,
bool agx_nir_lower_sample_intrinsics(struct nir_shader *shader,
bool ignore_sample_mask_without_msaa);
bool agx_nir_lower_alpha_to_coverage(struct nir_shader *shader,
uint8_t nr_samples);
bool agx_nir_lower_alpha_to_one(struct nir_shader *shader);
uint32_t agx_tilebuffer_total_size(struct agx_tilebuffer_layout *tib);
enum pipe_format

View file

@ -11,7 +11,6 @@ libasahi_lib_files = files(
'agx_linker.c',
'agx_bg_eot.c',
'agx_tilebuffer.c',
'agx_nir_lower_alpha.c',
'agx_nir_lower_gs.c',
'agx_nir_lower_ia.c',
'agx_nir_lower_msaa.c',

View file

@ -115,6 +115,7 @@ files_libnir = files(
'nir_loop_analyze.h',
'nir_lower_alu.c',
'nir_lower_alu_width.c',
'nir_lower_alpha.c',
'nir_lower_alpha_test.c',
'nir_lower_amul.c',
'nir_lower_array_deref_of_vec.c',

View file

@ -5222,6 +5222,12 @@ bool nir_lower_vec_to_regs(nir_shader *shader, nir_instr_writemask_filter_cb cb,
bool nir_lower_alpha_test(nir_shader *shader, enum compare_func func,
bool alpha_to_one,
const gl_state_index16 *alpha_ref_state_tokens);
bool nir_lower_alpha_to_coverage(nir_shader *shader,
uint8_t nr_samples);
bool nir_lower_alpha_to_one(nir_shader *shader);
bool nir_lower_alu(nir_shader *shader);
bool nir_lower_flrp(nir_shader *shader, unsigned lowering_mask,

View file

@ -806,7 +806,7 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK);
break;
case nir_intrinsic_discard_agx:
case nir_intrinsic_demote_samples:
shader->info.fs.uses_discard = true;
break;

View file

@ -1120,6 +1120,10 @@ barycentric("coord_at_offset", 3, [2])
intrinsic("load_sample_pos_from_id", src_comp=[1], dest_comp=2,
flags=[CAN_ELIMINATE, CAN_REORDER])
# Demote a subset of samples given by a specified sample mask. This acts like a
# per-sample demote, or an inverted accumulating gl_SampleMask write.
intrinsic("demote_samples", src_comp=[1])
intrinsic("load_persp_center_rhw_ir3", dest_comp=1,
flags=[CAN_ELIMINATE, CAN_REORDER])
@ -2173,12 +2177,6 @@ load("sysval_agx", [], [DESC_SET, BINDING, FLAGS], [CAN_REORDER, CAN_ELIMINATE])
# documented elsewhere as they are too complicated for this comment.
intrinsic("sample_mask_agx", src_comp=[1, 1])
# Discard a subset of samples given by a specified sample mask. This acts like a
# per-sample discard, or an inverted accumulating gl_SampleMask write. The
# compiler will lower to sample_mask_agx, but that lowering is nontrivial as
# sample_mask_agx also triggers depth/stencil testing.
intrinsic("discard_agx", src_comp=[1])
# For a given row of the polygon stipple given as an integer source in [0, 31],
# load the 32-bit stipple pattern for that row.
intrinsic("load_polygon_stipple_agx", src_comp=[1], dest_comp=1, bit_sizes=[32],

View file

@ -4,7 +4,6 @@
* SPDX-License-Identifier: MIT
*/
#include "agx_tilebuffer.h"
#include "nir.h"
#include "nir_builder.h"
@ -13,7 +12,7 @@
* monolithic pixel shader or a fragment epilogue.
*/
bool
agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
{
/* nir_lower_io_to_temporaries ensures that stores are in the last block */
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
@ -65,7 +64,7 @@ agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
nir_iadd_imm(b, nir_ishl(b, nir_imm_intN_t(b, 1, 16), bits), -1);
/* Discard samples that aren't covered */
nir_discard_agx(b, nir_inot(b, mask));
nir_demote_samples(b, nir_inot(b, mask));
shader->info.fs.uses_discard = true;
return nir_progress(true, impl, nir_metadata_control_flow);
}
@ -76,7 +75,7 @@ agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
* fragment epilogue.
*/
bool
agx_nir_lower_alpha_to_one(nir_shader *shader)
nir_lower_alpha_to_one(nir_shader *shader)
{
bool progress = false;