diff options
author | Kenneth Graunke <[email protected]> | 2010-12-27 00:22:38 -0800 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2010-12-27 00:59:31 -0800 |
commit | 9ac6a9b2fa45debac63f2e2b20d78c4776d06e37 (patch) | |
tree | 54998e214bb93f86ac57899e4367bcdf010d4163 /src/glsl | |
parent | 23aa3c552cc54a3242142b82916090f8b7b32e44 (diff) |
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.
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ir_optimization.h | 2 | ||||
-rw-r--r-- | src/glsl/lower_if_to_cond_assign.cpp | 42 |
2 files changed, 38 insertions, 6 deletions
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); @@ -120,8 +138,22 @@ 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; |