diff --git a/src/asahi/lib/agx_nir_lower_alpha.c b/src/asahi/lib/agx_nir_lower_alpha.c index fbb669e9538..9b533e6decb 100644 --- a/src/asahi/lib/agx_nir_lower_alpha.c +++ b/src/asahi/lib/agx_nir_lower_alpha.c @@ -5,13 +5,14 @@ */ #include "agx_tilebuffer.h" +#include "nir.h" #include "nir_builder.h" /* * Lower alpha-to-coverage to sample_mask and some math. May run on either a * monolithic pixel shader or a fragment epilogue. */ -void +bool agx_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 */ @@ -41,14 +42,14 @@ agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples) /* If render target 0 isn't written, the alpha value input to * alpha-to-coverage is undefined. We assume that the alpha would be 1.0, * which would effectively disable alpha-to-coverage, skipping the lowering. + * + * Similarly, if there are less than 4 components, alpha is undefined. */ - if (!store) - return; - - /* Similarly, if there are less than 4 components, alpha is undefined */ - nir_def *rgba = store->src[0].ssa; - if (rgba->num_components < 4) - return; + nir_def *rgba = store ? store->src[0].ssa : NULL; + if (!rgba || rgba->num_components < 4) { + nir_metadata_preserve(impl, nir_metadata_all); + return false; + } nir_builder _b = nir_builder_at(nir_before_instr(&store->instr)); nir_builder *b = &_b; @@ -67,6 +68,9 @@ agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples) /* Discard samples that aren't covered */ nir_discard_agx(b, nir_inot(b, mask)); shader->info.fs.uses_discard = true; + nir_metadata_preserve(impl, + nir_metadata_dominance | nir_metadata_block_index); + return true; } /* @@ -74,9 +78,11 @@ agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples) * alpha-to-one is used. May run on either a monolithic pixel shader or a * fragment epilogue. */ -void +bool agx_nir_lower_alpha_to_one(nir_shader *shader) { + bool progress = false; + /* nir_lower_io_to_temporaries ensures that stores are in the last block */ nir_function_impl *impl = nir_shader_get_entrypoint(shader); nir_block *block = nir_impl_last_block(impl); @@ -109,5 +115,15 @@ agx_nir_lower_alpha_to_one(nir_shader *shader) &b, rgba, nir_imm_floatN_t(&b, 1.0, rgba->bit_size), 3); nir_src_rewrite(&intr->src[0], rgb1); + progress = true; } + + if (progress) { + nir_metadata_preserve(impl, + nir_metadata_block_index | nir_metadata_dominance); + } else { + nir_metadata_preserve(impl, nir_metadata_all); + } + + return progress; } diff --git a/src/asahi/lib/agx_nir_lower_gs.c b/src/asahi/lib/agx_nir_lower_gs.c index 90fba752cd2..e975b9a5407 100644 --- a/src/asahi/lib/agx_nir_lower_gs.c +++ b/src/asahi/lib/agx_nir_lower_gs.c @@ -1034,7 +1034,7 @@ link_libagx(nir_shader *nir, const nir_shader *libagx) nir_address_format_62bit_generic); } -void +bool agx_nir_lower_gs(nir_shader *gs, nir_shader *vs, const nir_shader *libagx, struct agx_ia_key *ia, bool rasterizer_discard, nir_shader **gs_count, nir_shader **gs_copy, @@ -1218,6 +1218,7 @@ agx_nir_lower_gs(nir_shader *gs, nir_shader *vs, const nir_shader *libagx, /* Signal what primitive we want to draw the GS Copy VS with */ *out_mode = gs->info.gs.output_primitive; *out_count_words = gs_state.count_stride_el; + return true; } nir_shader * diff --git a/src/asahi/lib/agx_nir_lower_gs.h b/src/asahi/lib/agx_nir_lower_gs.h index e628fb1ad0d..3925f07e5da 100644 --- a/src/asahi/lib/agx_nir_lower_gs.h +++ b/src/asahi/lib/agx_nir_lower_gs.h @@ -12,11 +12,11 @@ struct nir_shader; struct agx_ia_key; enum mesa_prim; -void agx_nir_lower_ia(struct nir_shader *s, struct agx_ia_key *ia); +bool agx_nir_lower_ia(struct nir_shader *s, struct agx_ia_key *ia); -void agx_nir_lower_multidraw(struct nir_shader *s, struct agx_ia_key *key); +bool agx_nir_lower_multidraw(struct nir_shader *s, struct agx_ia_key *key); -void agx_nir_lower_gs(struct nir_shader *gs, struct nir_shader *vs, +bool agx_nir_lower_gs(struct nir_shader *gs, struct nir_shader *vs, const struct nir_shader *libagx, struct agx_ia_key *ia, bool rasterizer_discard, struct nir_shader **gs_count, struct nir_shader **gs_copy, struct nir_shader **pre_gs, diff --git a/src/asahi/lib/agx_nir_lower_ia.c b/src/asahi/lib/agx_nir_lower_ia.c index 3d0331257c5..c14e59191e3 100644 --- a/src/asahi/lib/agx_nir_lower_ia.c +++ b/src/asahi/lib/agx_nir_lower_ia.c @@ -79,12 +79,12 @@ lower_vertex_id(nir_builder *b, nir_intrinsic_instr *intr, void *data) return true; } -void +bool agx_nir_lower_ia(nir_shader *s, struct agx_ia_key *key) { - nir_shader_intrinsics_pass(s, lower_vertex_id, - nir_metadata_block_index | nir_metadata_dominance, - key); + return nir_shader_intrinsics_pass( + s, lower_vertex_id, nir_metadata_block_index | nir_metadata_dominance, + key); } struct multidraw_state { @@ -135,7 +135,7 @@ lower_multidraw(nir_builder *b, nir_intrinsic_instr *intr, void *data) return true; } -void +bool agx_nir_lower_multidraw(nir_shader *s, struct agx_ia_key *key) { assert(key->indirect_multidraw); @@ -171,4 +171,8 @@ agx_nir_lower_multidraw(nir_shader *s, struct agx_ia_key *key) b->cursor = nir_before_impl(b->impl); nir_def_rewrite_uses(state.raw_id, nir_load_primitive_id(b)); + + nir_metadata_preserve(b->impl, + nir_metadata_block_index | nir_metadata_dominance); + return true; } diff --git a/src/asahi/lib/agx_nir_predicate_layer_id.c b/src/asahi/lib/agx_nir_predicate_layer_id.c index 2dba0ccf5bb..16a6d7af800 100644 --- a/src/asahi/lib/agx_nir_predicate_layer_id.c +++ b/src/asahi/lib/agx_nir_predicate_layer_id.c @@ -40,15 +40,12 @@ lower(nir_builder *b, nir_intrinsic_instr *intr, void *_) return true; } -void +bool agx_nir_predicate_layer_id(nir_shader *shader) { assert(shader->info.stage == MESA_SHADER_FRAGMENT); + assert(shader->info.inputs_read & VARYING_BIT_LAYER); - /* If layer is not read, there's nothing to lower */ - if (shader->info.inputs_read & VARYING_BIT_LAYER) { - nir_shader_intrinsics_pass( - shader, lower, nir_metadata_block_index | nir_metadata_dominance, - NULL); - } + return nir_shader_intrinsics_pass( + shader, lower, nir_metadata_block_index | nir_metadata_dominance, NULL); } diff --git a/src/asahi/lib/agx_tilebuffer.h b/src/asahi/lib/agx_tilebuffer.h index e0911642af0..64091e79395 100644 --- a/src/asahi/lib/agx_tilebuffer.h +++ b/src/asahi/lib/agx_tilebuffer.h @@ -107,12 +107,12 @@ bool agx_nir_lower_monolithic_msaa(struct nir_shader *shader, bool agx_nir_lower_sample_intrinsics(struct nir_shader *shader); -void agx_nir_lower_alpha_to_coverage(struct nir_shader *shader, +bool agx_nir_lower_alpha_to_coverage(struct nir_shader *shader, uint8_t nr_samples); -void agx_nir_lower_alpha_to_one(struct nir_shader *shader); +bool agx_nir_lower_alpha_to_one(struct nir_shader *shader); -void agx_nir_predicate_layer_id(struct nir_shader *shader); +bool agx_nir_predicate_layer_id(struct nir_shader *shader); void agx_usc_tilebuffer(struct agx_usc_builder *b, struct agx_tilebuffer_layout *tib); diff --git a/src/gallium/drivers/asahi/agx_nir_lower_point_size.c b/src/gallium/drivers/asahi/agx_nir_lower_point_size.c index 8d90c27d284..b8a8a4a2c23 100644 --- a/src/gallium/drivers/asahi/agx_nir_lower_point_size.c +++ b/src/gallium/drivers/asahi/agx_nir_lower_point_size.c @@ -3,6 +3,7 @@ * SPDX-License-Identifier: MIT */ #include "agx_state.h" +#include "nir.h" #include "nir_builder.h" /* @@ -35,13 +36,13 @@ pass(nir_builder *b, nir_intrinsic_instr *intr, void *data) return true; } -void +bool agx_nir_lower_point_size(nir_shader *nir, bool fixed_point_size) { /* Handle existing point size write */ - nir_shader_intrinsics_pass(nir, pass, - nir_metadata_block_index | nir_metadata_dominance, - &fixed_point_size); + bool progress = nir_shader_intrinsics_pass( + nir, pass, nir_metadata_block_index | nir_metadata_dominance, + &fixed_point_size); /* Write the fixed-function point size if we have one */ if (fixed_point_size) { @@ -54,5 +55,10 @@ agx_nir_lower_point_size(nir_shader *nir, bool fixed_point_size) .io_semantics.num_slots = 1, .write_mask = nir_component_mask(1)); nir->info.outputs_written |= VARYING_BIT_PSIZ; + progress = true; + nir_metadata_preserve(b.impl, + nir_metadata_dominance | nir_metadata_block_index); } + + return progress; } diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 0f8d178e417..1c511c6cedd 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -1920,7 +1920,8 @@ agx_compile_variant(struct agx_device *dev, struct pipe_context *pctx, .api_sample_mask = key->api_sample_mask, }); - NIR_PASS_V(nir, agx_nir_predicate_layer_id); + if (nir->info.inputs_read & VARYING_BIT_LAYER) + NIR_PASS_V(nir, agx_nir_predicate_layer_id); } struct agx_shader_key base_key = {0}; diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 803ebc4799d..45267e40712 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -851,7 +851,7 @@ void agx_upload_uniforms(struct agx_batch *batch); uint64_t agx_upload_stage_uniforms(struct agx_batch *batch, uint64_t textures, enum pipe_shader_type stage); -void agx_nir_lower_point_size(nir_shader *nir, bool fixed_point_size); +bool agx_nir_lower_point_size(nir_shader *nir, bool fixed_point_size); bool agx_nir_lower_sysvals(nir_shader *shader, bool lower_draw_params);