Mesa (master): glsl: Add ir_binop_vector_extract

Ian Romanick idr at kemper.freedesktop.org
Mon May 13 19:06:53 UTC 2013


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

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Wed Mar  6 11:05:14 2013 -0800

glsl: Add ir_binop_vector_extract

The new opcode is used to get a single field from a vector.  The field
index may not be constant.  This will eventually replace
ir_dereference_array of vectors.  This is similar to the extractelement
instruction in LLVM IR.

http://llvm.org/docs/LangRef.html#extractelement-instruction

v2: Convert tabs to spaces.  Suggested by Eric.

v3: Add array index range checking to ir_binop_vector_extract constant
expression handling.  Suggested by Ken.

v4: Use CLAMP instead of MIN2(MAX2()).  Suggested by Ken.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Eric Anholt <eric at anholt.net>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/glsl/ir.cpp                     |    5 ++++
 src/glsl/ir.h                       |   10 ++++++++-
 src/glsl/ir_constant_expression.cpp |   38 +++++++++++++++++++++++++++++++---
 src/glsl/ir_validate.cpp            |    6 +++++
 src/mesa/program/ir_to_mesa.cpp     |    1 +
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 2c54525..737d8d4 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -399,6 +399,10 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
       this->type = op0->type;
       break;
 
+   case ir_binop_vector_extract:
+      this->type = op0->type->get_scalar_type();
+      break;
+
    default:
       assert(!"not reached: missing automatic type setup for ir_expression");
       this->type = glsl_type::float_type;
@@ -510,6 +514,7 @@ static const char *const operator_strs[] = {
    "packHalf2x16_split",
    "bfm",
    "ubo_load",
+   "vector_extract",
    "lrp",
    "bfi",
    "bitfield_extract",
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 6783eca..e3e3b71 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -1136,9 +1136,17 @@ enum ir_expression_operation {
    ir_binop_ubo_load,
 
    /**
+    * Extract a scalar from a vector
+    *
+    * operand0 is the vector
+    * operand1 is the index of the field to read from operand0
+    */
+   ir_binop_vector_extract,
+
+   /**
     * A sentinel marking the last of the binary operations.
     */
-   ir_last_binop = ir_binop_ubo_load,
+   ir_last_binop = ir_binop_vector_extract,
 
    ir_triop_lrp,
 
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
index a4a117e..990f983 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -391,10 +391,17 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
    }
 
    if (op[1] != NULL)
-      assert(op[0]->type->base_type == op[1]->type->base_type ||
-	     this->operation == ir_binop_lshift ||
-             this->operation == ir_binop_rshift ||
-             this->operation == ir_triop_bitfield_extract);
+      switch (this->operation) {
+      case ir_binop_lshift:
+      case ir_binop_rshift:
+      case ir_binop_vector_extract:
+      case ir_triop_bitfield_extract:
+         break;
+
+      default:
+         assert(op[0]->type->base_type == op[1]->type->base_type);
+         break;
+      }
 
    bool op0_scalar = op[0]->type->is_scalar();
    bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
@@ -1231,6 +1238,29 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
+   case ir_binop_vector_extract: {
+      const int c = CLAMP(op[1]->value.i[0], 0,
+			  (int) op[0]->type->vector_elements - 1);
+
+      switch (op[0]->type->base_type) {
+      case GLSL_TYPE_UINT:
+         data.u[0] = op[0]->value.u[c];
+         break;
+      case GLSL_TYPE_INT:
+         data.i[0] = op[0]->value.i[c];
+         break;
+      case GLSL_TYPE_FLOAT:
+         data.f[0] = op[0]->value.f[c];
+         break;
+      case GLSL_TYPE_BOOL:
+         data.b[0] = op[0]->value.b[c];
+         break;
+      default:
+         assert(0);
+      }
+      break;
+   }
+
    case ir_binop_bit_xor:
       for (unsigned c = 0, c0 = 0, c1 = 0;
            c < components;
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 26f09c7..03480cc 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -487,6 +487,12 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->operands[1]->type == glsl_type::uint_type);
       break;
 
+   case ir_binop_vector_extract:
+      assert(ir->operands[0]->type->is_vector());
+      assert(ir->operands[1]->type->is_scalar()
+             && ir->operands[1]->type->is_integer());
+      break;
+
    case ir_triop_lrp:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
       assert(ir->operands[0]->type == ir->operands[1]->type);
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 258b864..9828114 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1489,6 +1489,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       emit(ir, OPCODE_LRP, result_dst, op[2], op[1], op[0]);
       break;
 
+   case ir_binop_vector_extract:
    case ir_binop_bfm:
    case ir_triop_bfi:
    case ir_triop_bitfield_extract:




More information about the mesa-commit mailing list