From 4f91345f4923134b226ecd94e5636ea81c97e284 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Fri, 3 Jul 2020 12:01:17 +0200 Subject: [PATCH] ir3: Add layer_zero variant bit Part-of: --- src/freedreno/ir3/ir3_nir.c | 57 ++++++++++++++++++++++++++++++++++ src/freedreno/ir3/ir3_shader.c | 4 +++ src/freedreno/ir3/ir3_shader.h | 6 ++++ 3 files changed, 67 insertions(+) diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index 196c99f3024..f37d2994799 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -305,6 +305,61 @@ ir3_nir_post_finalize(struct ir3_compiler *compiler, nir_shader *s) ir3_optimize_loop(s); } +static bool +ir3_nir_lower_layer_id(nir_shader *nir) +{ + unsigned layer_id_loc = ~0; + nir_foreach_variable(var, &nir->inputs) { + if (var->data.location == VARYING_SLOT_LAYER) { + layer_id_loc = var->data.driver_location; + break; + } + } + + assert(layer_id_loc != ~0); + + bool progress = false; + nir_builder b; + + nir_foreach_function(func, nir) { + nir_builder_init(&b, func->impl); + + nir_foreach_block(block, func->impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type != nir_instr_type_intrinsic) + continue; + + nir_intrinsic_instr *intrin = + nir_instr_as_intrinsic(instr); + + if (intrin->intrinsic != nir_intrinsic_load_input) + continue; + + unsigned base = nir_intrinsic_base(intrin); + if (base != layer_id_loc) + continue; + + b.cursor = nir_before_instr(&intrin->instr); + nir_ssa_def *zero = nir_imm_int(&b, 0); + nir_ssa_def_rewrite_uses(&intrin->dest.ssa, + nir_src_for_ssa(zero)); + nir_instr_remove(&intrin->instr); + progress = true; + } + } + + if (progress) { + nir_metadata_preserve(func->impl, + nir_metadata_block_index | + nir_metadata_dominance); + } else { + nir_metadata_preserve(func->impl, nir_metadata_all); + } + } + + return progress; +} + void ir3_nir_lower_variant(struct ir3_shader_variant *so, nir_shader *s) { @@ -352,6 +407,8 @@ ir3_nir_lower_variant(struct ir3_shader_variant *so, nir_shader *s) progress |= OPT(s, nir_lower_clip_fs, so->key.ucp_enables, false); if (so->key.fclamp_color) progress |= OPT(s, nir_lower_clamp_color_outputs); + if (so->key.layer_zero && (s->info.inputs_read & VARYING_BIT_LAYER)) + progress |= OPT(s, ir3_nir_lower_layer_id); } if (so->key.color_two_side) { OPT_V(s, nir_lower_two_sided_color); diff --git a/src/freedreno/ir3/ir3_shader.c b/src/freedreno/ir3/ir3_shader.c index 984ae57418d..9771c66faf6 100644 --- a/src/freedreno/ir3/ir3_shader.c +++ b/src/freedreno/ir3/ir3_shader.c @@ -354,6 +354,10 @@ ir3_setup_used_key(struct ir3_shader *shader) key->color_two_side = true; } + if (info->inputs_read & VARYING_BIT_LAYER) { + key->layer_zero = true; + } + if ((info->outputs_written & ~(FRAG_RESULT_DEPTH | FRAG_RESULT_STENCIL | FRAG_RESULT_SAMPLE_MASK)) != 0) { diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index 7430bed03f7..f5810847112 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -318,6 +318,9 @@ struct ir3_shader_key { * the limit: */ unsigned safe_constlen : 1; + + /* Whether gl_Layer must be forced to 0 because it isn't written. */ + unsigned layer_zero : 1; }; uint32_t global; }; @@ -385,6 +388,9 @@ ir3_shader_key_changes_fs(struct ir3_shader_key *key, struct ir3_shader_key *las if (last_key->rasterflat != key->rasterflat) return true; + if (last_key->layer_zero != key->layer_zero) + return true; + if (last_key->ucp_enables != key->ucp_enables) return true; -- 2.30.2