From: Kenneth Graunke Date: Mon, 27 Dec 2010 08:22:38 +0000 (-0800) Subject: glsl: Support if-flattening beyond a given maximum nesting depth. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9ac6a9b2fa45debac63f2e2b20d78c4776d06e37;p=mesa.git glsl: Support if-flattening beyond a given maximum nesting depth. This adds a new optional max_depth parameter (defaulting to 0) to lower_if_to_cond_assign, and makes the pass only flatten if-statements nested deeper than that. By default, all if-statements will be flattened, just like before. This patch also renames do_if_to_cond_assign to lower_if_to_cond_assign, to match the new naming conventions. --- diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index f264265f4b1..dbc9f4ab975 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -53,7 +53,7 @@ bool do_lower_jumps(exec_list *instructions, bool pull_out_jumps = true, bool lo bool do_lower_texture_projection(exec_list *instructions); bool do_if_simplification(exec_list *instructions); bool do_discard_simplification(exec_list *instructions); -bool do_if_to_cond_assign(exec_list *instructions); +bool lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth = 0); bool do_mat_op_to_vec(exec_list *instructions); bool do_mod_to_fract(exec_list *instructions); bool do_noop_swizzle(exec_list *instructions); diff --git a/src/glsl/lower_if_to_cond_assign.cpp b/src/glsl/lower_if_to_cond_assign.cpp index cf48cfb8d61..40ffc45c86c 100644 --- a/src/glsl/lower_if_to_cond_assign.cpp +++ b/src/glsl/lower_if_to_cond_assign.cpp @@ -24,12 +24,25 @@ /** * \file lower_if_to_cond_assign.cpp * - * This attempts to flatten all if statements to conditional - * assignments for GPUs that don't do control flow. + * This attempts to flatten if-statements to conditional assignments for + * GPUs with limited or no flow control support. * * It can't handle other control flow being inside of its block, such * as calls or loops. Hopefully loop unrolling and inlining will take * care of those. + * + * Drivers for GPUs with no control flow support should simply call + * + * lower_if_to_cond_assign(instructions) + * + * to attempt to flatten all if-statements. + * + * Some GPUs (such as i965 prior to gen6) do support control flow, but have a + * maximum nesting depth N. Drivers for such hardware can call + * + * lower_if_to_cond_assign(instructions, N) + * + * to attempt to flatten any if-statements appearing at depth > N. */ #include "glsl_types.h" @@ -37,20 +50,25 @@ class ir_if_to_cond_assign_visitor : public ir_hierarchical_visitor { public: - ir_if_to_cond_assign_visitor() + ir_if_to_cond_assign_visitor(unsigned max_depth) { this->progress = false; + this->max_depth = max_depth; + this->depth = 0; } + ir_visitor_status visit_enter(ir_if *); ir_visitor_status visit_leave(ir_if *); bool progress; + unsigned max_depth; + unsigned depth; }; bool -do_if_to_cond_assign(exec_list *instructions) +lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth) { - ir_if_to_cond_assign_visitor v; + ir_if_to_cond_assign_visitor v(max_depth); visit_list_elements(&v, instructions); @@ -119,9 +137,23 @@ move_block_to_cond_assign(void *mem_ctx, } } +ir_visitor_status +ir_if_to_cond_assign_visitor::visit_enter(ir_if *ir) +{ + (void) ir; + this->depth++; + return visit_continue; +} + ir_visitor_status ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) { + /* Only flatten when beyond the GPU's maximum supported nesting depth. */ + if (this->depth <= this->max_depth) + return visit_continue; + + this->depth--; + bool found_control_flow = false; ir_variable *cond_var; ir_assignment *assign; diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 490c4cab7ab..c601ef6eaaa 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2867,7 +2867,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) if (options->EmitNoIfs) { progress = lower_discard(ir) || progress; - progress = do_if_to_cond_assign(ir) || progress; + progress = lower_if_to_cond_assign(ir) || progress; } if (options->EmitNoNoise)