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>tags/mesa-9.2-rc1
@@ -518,6 +518,7 @@ static const char *const operator_strs[] = { | |||
"lrp", | |||
"bfi", | |||
"bitfield_extract", | |||
"vector_insert", | |||
"bitfield_insert", | |||
"vector", | |||
}; |
@@ -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, | |||
@@ -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]; |
@@ -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); |
@@ -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; |