Mesa (master): mesa: Add new ir_unop_any() expression operation.

Eric Anholt anholt at kemper.freedesktop.org
Mon Aug 23 20:07:06 UTC 2010


Module: Mesa
Branch: master
Commit: 5e9ac94cc44ef4f97063d7b696411b2a4be16f36
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5e9ac94cc44ef4f97063d7b696411b2a4be16f36

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 23 12:21:33 2010 -0700

mesa: Add new ir_unop_any() expression operation.

The previous any() implementation would generate arg0.x || arg0.y ||
arg0.z.  Having an expression operation for this makes it easy for the
backend to generate something easier (DPn + SNE for 915 FS, .any
predication on 965 VS)

---

 src/glsl/README                     |    1 +
 src/glsl/builtins/ir/any            |    6 +++---
 src/glsl/ir.cpp                     |    2 ++
 src/glsl/ir.h                       |    1 +
 src/glsl/ir_constant_expression.cpp |    9 +++++++++
 src/glsl/ir_validate.cpp            |    5 +++++
 src/mesa/program/ir_to_mesa.cpp     |   20 ++++++++++++++++++++
 7 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/src/glsl/README b/src/glsl/README
index 7452032..2e501d6 100644
--- a/src/glsl/README
+++ b/src/glsl/README
@@ -180,6 +180,7 @@ ir.h (new enum)
 ir.cpp:get_num_operands() (used for ir_reader)
 ir.cpp:operator_strs (used for ir_reader)
 ir_constant_expression.cpp (you probably want to be able to constant fold)
+ir_validate.cpp (check users have the right types)
 
 You may also need to update the backends if they will see the new expr type:
 
diff --git a/src/glsl/builtins/ir/any b/src/glsl/builtins/ir/any
index f10e8a7..cc6038a 100644
--- a/src/glsl/builtins/ir/any
+++ b/src/glsl/builtins/ir/any
@@ -2,15 +2,15 @@
    (signature bool
      (parameters
        (declare (in) bvec2 arg0))
-     ((return (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))
+     ((return (expression bool any (var_ref arg0)))))
 
    (signature bool
      (parameters
        (declare (in) bvec3 arg0))
-     ((return (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))
+     ((return (expression bool any (var_ref arg0)))))
 
    (signature bool
      (parameters
        (declare (in) bvec4 arg0))
-     ((return (expression bool || (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))
+     ((return (expression bool any (var_ref arg0)))))
 ))
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index ebb5927..4622a1f 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -184,6 +184,7 @@ ir_expression::get_num_operands(ir_expression_operation op)
       1, /* ir_unop_i2b */
       1, /* ir_unop_b2i */
       1, /* ir_unop_u2f */
+      1, /* ir_unop_any */
 
       1, /* ir_unop_trunc */
       1, /* ir_unop_ceil */
@@ -252,6 +253,7 @@ static const char *const operator_strs[] = {
    "i2b",
    "b2i",
    "u2f",
+   "any",
    "trunc",
    "ceil",
    "floor",
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index b042228..500b152 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -604,6 +604,7 @@ enum ir_expression_operation {
    ir_unop_i2b,      /**< int-to-boolean conversion */
    ir_unop_b2i,      /**< Boolean-to-int conversion */
    ir_unop_u2f,      /**< Unsigned-to-float conversion. */
+   ir_unop_any,
 
    /**
     * \name Unary floating-point rounding operations.
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
index 54f14d1..942f198 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -149,6 +149,15 @@ ir_expression::constant_expression_value()
       }
       break;
 
+   case ir_unop_any:
+      assert(op[0]->type->is_boolean());
+      data.b[0] = false;
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+	 if (op[0]->value.b[c])
+	    data.b[0] = true;
+      }
+      break;
+
    case ir_unop_trunc:
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
       for (unsigned c = 0; c < op[0]->type->components(); c++) {
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 6e08fa4..9ea11dd 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -223,6 +223,11 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->type->base_type == GLSL_TYPE_FLOAT);
       break;
 
+   case ir_unop_any:
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
+      assert(ir->type == glsl_type::bool_type);
+      break;
+
    case ir_unop_trunc:
    case ir_unop_ceil:
    case ir_unop_floor:
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 7a615f2..ea2560a 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -844,6 +844,26 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
 	 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
       }
       break;
+
+   case ir_unop_any:
+      switch (ir->operands[0]->type->vector_elements) {
+      case 4:
+	 ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, op[0], op[0]);
+	 break;
+      case 3:
+	 ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, op[0], op[0]);
+	 break;
+      case 2:
+	 ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, op[0], op[0]);
+	 break;
+      default:
+	 assert(!"unreached: ir_unop_any of non-bvec");
+	 break;
+      }
+      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+			  result_dst, result_src, src_reg_for_float(0.0));
+      break;
+
    case ir_binop_logic_xor:
       ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
       break;




More information about the mesa-commit mailing list