diff options
author | Daniel Schürmann <[email protected]> | 2019-07-18 13:39:49 +0200 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2019-07-24 13:02:18 -0500 |
commit | e272fdd508f844f6545827273b3cf2f109759a6d (patch) | |
tree | 9fd5aea1f0f1e49ded60d094001c8a779b3f3ed2 | |
parent | 517005b4cf376b292f61d786d419e2a611e4a02a (diff) |
nir,intel: lower if (cond) demote() to new intrinsic demote_if(cond)
This will effectively enable the optimization in anv.
Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r-- | src/compiler/nir/nir_gather_info.c | 1 | ||||
-rw-r--r-- | src/compiler/nir/nir_intrinsics.py | 3 | ||||
-rw-r--r-- | src/compiler/nir/nir_opt_conditional_discard.c | 41 | ||||
-rw-r--r-- | src/compiler/nir/nir_opt_constant_folding.c | 11 | ||||
-rw-r--r-- | src/intel/compiler/brw_fs_nir.cpp | 4 |
5 files changed, 38 insertions, 22 deletions
diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index a7e258d6d9d..b6e6b0afd1f 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -199,6 +199,7 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader, { switch (instr->intrinsic) { case nir_intrinsic_demote: + case nir_intrinsic_demote_if: case nir_intrinsic_discard: case nir_intrinsic_discard_if: assert(shader->info.stage == MESA_SHADER_FRAGMENT); diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 373153a8db4..50823a1532c 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -241,8 +241,9 @@ barrier("memory_barrier_shared") barrier("begin_invocation_interlock") barrier("end_invocation_interlock") -# A conditional discard, with a single boolean source. +# A conditional discard/demote, with a single boolean source. intrinsic("discard_if", src_comp=[1]) +intrinsic("demote_if", src_comp=[1]) # ARB_shader_group_vote intrinsics intrinsic("vote_any", src_comp=[1], dest_comp=1, flags=[CAN_ELIMINATE]) diff --git a/src/compiler/nir/nir_opt_conditional_discard.c b/src/compiler/nir/nir_opt_conditional_discard.c index 3605eaf272f..781438df06e 100644 --- a/src/compiler/nir/nir_opt_conditional_discard.c +++ b/src/compiler/nir/nir_opt_conditional_discard.c @@ -26,7 +26,9 @@ /** @file nir_opt_conditional_discard.c * - * Handles optimization of lowering if (cond) discard to discard_if(cond). + * Handles optimization of lowering of + * - if (cond) discard to discard_if(cond) and + * - if (cond) demote to demote_if(cond) */ static bool @@ -73,30 +75,37 @@ nir_opt_conditional_discard_block(nir_builder *b, nir_block *block) } /* Get the first instruction in the then block and confirm it is - * a discard or a discard_if + * a discard or a demote instruction. */ nir_instr *instr = nir_block_first_instr(then_block); if (instr->type != nir_instr_type_intrinsic) return false; nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); - if (intrin->intrinsic != nir_intrinsic_discard && - intrin->intrinsic != nir_intrinsic_discard_if) - return false; - - nir_src cond; - + nir_intrinsic_op op = intrin->intrinsic; + assert(if_stmt->condition.is_ssa); + nir_ssa_def *cond = if_stmt->condition.ssa; b->cursor = nir_before_cf_node(prev_node); - if (intrin->intrinsic == nir_intrinsic_discard) - cond = if_stmt->condition; - else - cond = nir_src_for_ssa(nir_iand(b, - nir_ssa_for_src(b, if_stmt->condition, 1), - nir_ssa_for_src(b, intrin->src[0], 1))); + + switch (intrin->intrinsic) { + case nir_intrinsic_discard: + op = nir_intrinsic_discard_if; + break; + case nir_intrinsic_demote: + op = nir_intrinsic_demote_if; + break; + case nir_intrinsic_discard_if: + case nir_intrinsic_demote_if: + assert(intrin->src[0].is_ssa); + cond = nir_iand(b, cond, intrin->src[0].ssa); + break; + default: + return false; + } nir_intrinsic_instr *discard_if = - nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if); - nir_src_copy(&discard_if->src[0], &cond, discard_if); + nir_intrinsic_instr_create(b->shader, op); + discard_if->src[0] = nir_src_for_ssa(cond); nir_instr_insert_before_cf(prev_node, &discard_if->instr); nir_instr_remove(&intrin->instr); diff --git a/src/compiler/nir/nir_opt_constant_folding.c b/src/compiler/nir/nir_opt_constant_folding.c index 84dbce5ac30..38d011536bb 100644 --- a/src/compiler/nir/nir_opt_constant_folding.c +++ b/src/compiler/nir/nir_opt_constant_folding.c @@ -119,7 +119,8 @@ constant_fold_intrinsic_instr(nir_intrinsic_instr *instr) { bool progress = false; - if (instr->intrinsic == nir_intrinsic_discard_if && + if ((instr->intrinsic == nir_intrinsic_demote_if || + instr->intrinsic == nir_intrinsic_discard_if) && nir_src_is_const(instr->src[0])) { if (nir_src_as_bool(instr->src[0])) { /* This method of getting a nir_shader * from a nir_instr is @@ -131,9 +132,11 @@ constant_fold_intrinsic_instr(nir_intrinsic_instr *instr) nir_function_impl *impl = nir_cf_node_get_function(cf_node); nir_shader *shader = impl->function->shader; - nir_intrinsic_instr *discard = - nir_intrinsic_instr_create(shader, nir_intrinsic_discard); - nir_instr_insert_before(&instr->instr, &discard->instr); + nir_intrinsic_op op = instr->intrinsic == nir_intrinsic_discard_if ? + nir_intrinsic_discard : + nir_intrinsic_demote; + nir_intrinsic_instr *new_instr = nir_intrinsic_instr_create(shader, op); + nir_instr_insert_before(&instr->instr, &new_instr->instr); nir_instr_remove(&instr->instr); progress = true; } else { diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp index 6ea012c74b6..0b3982737dd 100644 --- a/src/intel/compiler/brw_fs_nir.cpp +++ b/src/intel/compiler/brw_fs_nir.cpp @@ -3568,6 +3568,7 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld, case nir_intrinsic_demote: case nir_intrinsic_discard: + case nir_intrinsic_demote_if: case nir_intrinsic_discard_if: { /* We track our discarded pixels in f0.1. By predicating on it, we can * update just the flag bits that aren't yet discarded. If there's no @@ -3575,7 +3576,8 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld, * channels will get turned off. */ fs_inst *cmp = NULL; - if (instr->intrinsic == nir_intrinsic_discard_if) { + if (instr->intrinsic == nir_intrinsic_demote_if || + instr->intrinsic == nir_intrinsic_discard_if) { nir_alu_instr *alu = nir_src_as_alu_instr(instr->src[0]); if (alu != NULL && |