summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2013-03-12 12:42:51 -0700
committerIan Romanick <[email protected]>2013-05-13 12:05:18 -0700
commitdafd6918f305274c8374bf9d427d90a3dabe13cb (patch)
treeffedaac8613427a35f801b23cc8865583655a130
parentf274a2ca8733059bdd4f1c456ed4f6df7d7ec008 (diff)
glsl: Add ir_triop_vector_insert
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 <[email protected]> Reviewed-by: Eric Anholt <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/glsl/ir.cpp1
-rw-r--r--src/glsl/ir.h11
-rw-r--r--src/glsl/ir_constant_expression.cpp25
-rw-r--r--src/glsl/ir_validate.cpp9
-rw-r--r--src/mesa/program/ir_to_mesa.cpp1
5 files changed, 46 insertions, 1 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 737d8d43f63..dad58deeb97 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -518,6 +518,7 @@ static const char *const operator_strs[] = {
"lrp",
"bfi",
"bitfield_extract",
+ "vector_insert",
"bitfield_insert",
"vector",
};
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index e3e3b7119a8..6d4150136cd 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -1162,9 +1162,18 @@ 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,
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
index 990f9835d99..0a725b45bc4 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -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];
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 03480ccd364..5db25763c69 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -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);
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 98281140aae..e9c332d1543 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -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;