Mesa (7.10): glsl: Support if-flattening beyond a given maximum nesting depth.

Ian Romanick idr at kemper.freedesktop.org
Tue Jan 4 17:59:29 UTC 2011


Module: Mesa
Branch: 7.10
Commit: 9d3573c905298f2e5c4d60f0a967d14923148ad6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9d3573c905298f2e5c4d60f0a967d14923148ad6

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Mon Dec 27 00:22:38 2010 -0800

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.
(cherry picked from commit 9ac6a9b2fa45debac63f2e2b20d78c4776d06e37)

---

 src/glsl/ir_optimization.h           |    2 +-
 src/glsl/lower_if_to_cond_assign.cpp |   42 +++++++++++++++++++++++++++++----
 src/mesa/program/ir_to_mesa.cpp      |    2 +-
 3 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index f264265..dbc9f4a 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 cf48cfb..40ffc45 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;
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 490c4ca..c601ef6 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)




More information about the mesa-commit mailing list