[Mesa-dev] [PATCH] glsl: flatten ifs with discard statements in lower_if_to_cond_assign

Marek Olšák maraeo at gmail.com
Wed Nov 24 14:24:12 PST 2010


Signed-off-by: Marek Olšák <maraeo at gmail.com>
Cc: Eric Anholt <eric at anholt.net>
---
 src/glsl/lower_if_to_cond_assign.cpp |   24 +++++++++++++++---------
 src/glsl/lower_jumps.cpp             |    4 +++-
 src/mesa/program/ir_to_mesa.cpp      |   10 +++++++---
 3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/src/glsl/lower_if_to_cond_assign.cpp b/src/glsl/lower_if_to_cond_assign.cpp
index cf48cfb..4497b13 100644
--- a/src/glsl/lower_if_to_cond_assign.cpp
+++ b/src/glsl/lower_if_to_cond_assign.cpp
@@ -63,7 +63,6 @@ check_control_flow(ir_instruction *ir, void *data)
    bool *found_control_flow = (bool *)data;
    switch (ir->ir_type) {
    case ir_type_call:
-   case ir_type_discard:
    case ir_type_loop:
    case ir_type_loop_jump:
    case ir_type_return:
@@ -89,10 +88,17 @@ move_block_to_cond_assign(void *mem_ctx,
    foreach_iter(exec_list_iterator, iter, *instructions) {
       ir_instruction *ir = (ir_instruction *)iter.get();
 
-      if (ir->ir_type == ir_type_assignment) {
-	 ir_assignment *assign = (ir_assignment *)ir;
+      if (ir->ir_type == ir_type_assignment ||
+          ir->ir_type == ir_type_discard) {
 	 ir_rvalue *cond_expr;
 	 ir_dereference *deref = new(mem_ctx) ir_dereference_variable(cond_var);
+	 ir_rvalue **condition;
+
+	 if (ir->ir_type == ir_type_assignment) {
+	    condition = &((ir_assignment *)ir)->condition;
+	 } else {
+	    condition = &((ir_discard *)ir)->condition;
+	 }
 
 	 if (then) {
 	    cond_expr = deref;
@@ -103,13 +109,13 @@ move_block_to_cond_assign(void *mem_ctx,
 						   NULL);
 	 }
 
-	 if (!assign->condition) {
-	    assign->condition = cond_expr;
+	 if (!*condition) {
+	    *condition = cond_expr;
 	 } else {
-	    assign->condition = new(mem_ctx) ir_expression(ir_binop_logic_and,
-							   glsl_type::bool_type,
-							   cond_expr,
-							   assign->condition);
+	    *condition = new(mem_ctx) ir_expression(ir_binop_logic_and,
+						    glsl_type::bool_type,
+						    cond_expr,
+						    *condition);
 	 }
       }
 
diff --git a/src/glsl/lower_jumps.cpp b/src/glsl/lower_jumps.cpp
index e1e7a5b..857c985 100644
--- a/src/glsl/lower_jumps.cpp
+++ b/src/glsl/lower_jumps.cpp
@@ -202,7 +202,9 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
 
    virtual void visit(class ir_discard * ir)
    {
-      truncate_after_instruction(ir);
+      if (!ir->condition) {
+         truncate_after_instruction(ir);
+      }
       this->block.min_strength = strength_discard;
    }
 
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 8f75c82..ff372a7 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2166,9 +2166,13 @@ ir_to_mesa_visitor::visit(ir_discard *ir)
 {
    struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
 
-   assert(ir->condition == NULL); /* FINISHME */
-
-   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
+   if (ir->condition) {
+      ir->condition->accept(this);
+      this->result.negate = ~this->result.negate;
+      ir_to_mesa_emit_op1(ir, OPCODE_KIL, ir_to_mesa_undef_dst, this->result);
+   } else {
+      ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
+   }
    fp->UsesKill = GL_TRUE;
 }
 
-- 
1.7.0.4



More information about the mesa-dev mailing list