From: Ian Romanick Date: Tue, 12 Mar 2013 19:42:51 +0000 (-0700) Subject: glsl: Add ir_triop_vector_insert X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dafd6918f305274c8374bf9d427d90a3dabe13cb;p=mesa.git 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 Reviewed-by: Eric Anholt Reviewed-by: Kenneth Graunke --- 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 @@ -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, 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;