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@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Ian Romanick
2013-03-06 11:05:14 -08:00
parent b0bb6103d2
commit f274a2ca87
5 changed files with 55 additions and 5 deletions

View File

@@ -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;