glsl: Add ir_triop_vector_insert
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 12 Mar 2013 19:42:51 +0000 (12:42 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 13 May 2013 19:05:18 +0000 (12:05 -0700)
The new opcode is used to generate a new vector with a single field from
the source vector replaced.  This will eventually replace
ir_dereference_array of vectors in the LHS of assignments.

v2: Convert tabs to spaces.  Suggested by Eric.

v3: Add constant expression handling for ir_triop_vector_insert.  This
prevents the constant matrix inversion tests from regressing.  Duh.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_constant_expression.cpp
src/glsl/ir_validate.cpp
src/mesa/program/ir_to_mesa.cpp

index 737d8d43f63ad09c6ca801147c1c595ae00a36d8..dad58deeb97aa8a874ee3621178bb054a7df9919 100644 (file)
@@ -518,6 +518,7 @@ static const char *const operator_strs[] = {
    "lrp",
    "bfi",
    "bitfield_extract",
+   "vector_insert",
    "bitfield_insert",
    "vector",
 };
index e3e3b7119a823d62d848ed9eac10462626c1cb5f..6d4150136cd8c75b85da4d3c89152851d4f5bfb5 100644 (file)
@@ -1161,10 +1161,19 @@ enum ir_expression_operation {
 
    ir_triop_bitfield_extract,
 
+   /**
+    * Generate a value with one field of a vector changed
+    *
+    * operand0 is the vector
+    * operand1 is the value to write into the vector result
+    * operand2 is the index in operand0 to be modified
+    */
+   ir_triop_vector_insert,
+
    /**
     * A sentinel marking the last of the ternary operations.
     */
-   ir_last_triop = ir_triop_bitfield_extract,
+   ir_last_triop = ir_triop_vector_insert,
 
    ir_quadop_bitfield_insert,
 
index 990f9835d99910661240416f62ea79502bf8a55e..0a725b45bc47f8cb2051caedfe4e1e09dea5983d 100644 (file)
@@ -1388,6 +1388,31 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       break;
    }
 
+   case ir_triop_vector_insert: {
+      const unsigned idx = op[2]->value.u[0];
+
+      memcpy(&data, &op[0]->value, sizeof(data));
+
+      switch (this->type->base_type) {
+      case GLSL_TYPE_INT:
+        data.i[idx] = op[1]->value.i[0];
+        break;
+      case GLSL_TYPE_UINT:
+        data.u[idx] = op[1]->value.u[0];
+        break;
+      case GLSL_TYPE_FLOAT:
+        data.f[idx] = op[1]->value.f[0];
+        break;
+      case GLSL_TYPE_BOOL:
+        data.b[idx] = op[1]->value.b[0];
+        break;
+      default:
+        assert(!"Should not get here.");
+        break;
+      }
+      break;
+   }
+
    case ir_quadop_bitfield_insert: {
       int offset = op[2]->value.i[0];
       int bits = op[3]->value.i[0];
index 03480ccd36473ddadfb72d961cdc1f4d3fef174f..5db25763c69648bbe844006aaed0f995fda86a25 100644 (file)
@@ -511,6 +511,15 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->operands[2]->type == glsl_type::int_type);
       break;
 
+   case ir_triop_vector_insert:
+      assert(ir->operands[0]->type->is_vector());
+      assert(ir->operands[1]->type->is_scalar());
+      assert(ir->operands[0]->type->base_type == ir->operands[1]->type->base_type);
+      assert(ir->operands[2]->type->is_scalar()
+             && ir->operands[2]->type->is_integer());
+      assert(ir->type == ir->operands[0]->type);
+      break;
+
    case ir_quadop_bitfield_insert:
       assert(ir->operands[0]->type == ir->type);
       assert(ir->operands[1]->type == ir->type);
index 98281140aae05aa36b53c7c7d114ce64bc2d9f2c..e9c332d154359c8f9ae7eb0e16d9d01907a37f3d 100644 (file)
@@ -1493,6 +1493,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
    case ir_binop_bfm:
    case ir_triop_bfi:
    case ir_triop_bitfield_extract:
+   case ir_triop_vector_insert:
    case ir_quadop_bitfield_insert:
       assert(!"not supported");
       break;