From f274a2ca8733059bdd4f1c456ed4f6df7d7ec008 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 6 Mar 2013 11:05:14 -0800 Subject: 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 Reviewed-by: Eric Anholt Reviewed-by: Kenneth Graunke --- src/glsl/ir_constant_expression.cpp | 38 +++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'src/glsl/ir_constant_expression.cpp') diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index a4a117e683d..990f9835d99 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -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; -- cgit v1.2.3