Module: Mesa Branch: main Commit: c5712410ec3d65ae6cd759661883868912a903dd URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=c5712410ec3d65ae6cd759661883868912a903dd
Author: Emma Anholt <[email protected]> Date: Tue Oct 3 10:04:04 2023 -0700 nir: Flatten ifs with discards in nir_opt_peephole_select for HW without CF. i915g and r300-r400 don't have if statements, and discards are all nir_intrinsic_discard_if. We can flatten those discards here, saving a separate GLSL pass to try to do so. i915g: GAINED: shaders/closed/xcom-enemy-unknown/413.shader_test FS rv370: GAINED: shaders/closed/xcom-enemy-unknown/12.shader_test FS GAINED: shaders/closed/xcom-enemy-unknown/122.shader_test FS GAINED: shaders/closed/xcom-enemy-unknown/132.shader_test FS GAINED: shaders/closed/xcom-enemy-unknown/145.shader_test FS GAINED: shaders/closed/xcom-enemy-unknown/146.shader_test FS GAINED: shaders/closed/xcom-enemy-unknown/19.shader_test FS GAINED: shaders/closed/xcom-enemy-unknown/413.shader_test FS GAINED: shaders/closed/xcom-enemy-unknown/415.shader_test FS Closes: #9918 Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24763> --- src/compiler/nir/nir_opt_peephole_select.c | 46 ++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c index 9de5402d7f7..043e1bad041 100644 --- a/src/compiler/nir/nir_opt_peephole_select.c +++ b/src/compiler/nir/nir_opt_peephole_select.c @@ -23,6 +23,7 @@ #include "nir/nir_builder.h" #include "nir.h" +#include "nir_builder.h" #include "nir_control_flow.h" #include "nir_search_helpers.h" @@ -74,10 +75,21 @@ block_check_for_allowed_instrs(nir_block *block, unsigned *count, case nir_instr_type_tex: break; - case nir_instr_type_intrinsic: - if (!nir_intrinsic_can_reorder(nir_instr_as_intrinsic(instr))) - return false; + case nir_instr_type_intrinsic: { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + switch (intr->intrinsic) { + case nir_intrinsic_discard: + case nir_intrinsic_discard_if: + /* For non-CF hardware, we need to be able to move discards up + * and flatten, so let them pass. + */ + continue; + default: + if (!nir_intrinsic_can_reorder(intr)) + return false; + } break; + } case nir_instr_type_call: case nir_instr_type_jump: @@ -362,6 +374,32 @@ nir_opt_collapse_if(nir_if *if_stmt, nir_shader *shader, unsigned limit, return true; } +/* If we're moving discards out of the if for non-CF hardware, we need to add + * the if's condition to it + */ +static void +rewrite_discard_conds(nir_instr *instr, nir_def *if_cond, bool is_else) +{ + if (instr->type != nir_instr_type_intrinsic) + return; + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + + if (intr->intrinsic != nir_intrinsic_discard_if && intr->intrinsic != nir_intrinsic_discard) + return; + + nir_builder b = nir_builder_at(nir_before_instr(instr)); + + if (is_else) + if_cond = nir_inot(&b, if_cond); + + if (intr->intrinsic == nir_intrinsic_discard_if) { + nir_src_rewrite(&intr->src[0], nir_iand(&b, intr->src[0].ssa, if_cond)); + } else { + nir_discard_if(&b, if_cond); + nir_instr_remove(instr); + } +} + static bool nir_opt_peephole_select_block(nir_block *block, nir_shader *shader, unsigned limit, bool indirect_load_ok, @@ -434,12 +472,14 @@ nir_opt_peephole_select_block(nir_block *block, nir_shader *shader, exec_node_remove(&instr->node); instr->block = prev_block; exec_list_push_tail(&prev_block->instr_list, &instr->node); + rewrite_discard_conds(instr, if_stmt->condition.ssa, false); } nir_foreach_instr_safe(instr, else_block) { exec_node_remove(&instr->node); instr->block = prev_block; exec_list_push_tail(&prev_block->instr_list, &instr->node); + rewrite_discard_conds(instr, if_stmt->condition.ssa, true); } nir_foreach_phi_safe(phi, block) {
