It's a ?: that operates per-component on vectors. Will be used in upcoming lowering passes for frexp and ldexp. --- src/glsl/ir.cpp | 25 +++++++++++++++++++++++++ src/glsl/ir.h | 18 ++++++++++++++++++ src/glsl/ir_builder.cpp | 14 ++++++++++++++ src/glsl/ir_builder.h | 2 ++ src/glsl/ir_constant_expression.cpp | 8 ++++++++ src/glsl/ir_validate.cpp | 7 +++++++ src/mesa/program/ir_to_mesa.cpp | 1 + src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 1 + 8 files changed, 76 insertions(+)
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index c8d8802..46bc608 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -409,6 +409,30 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) } } +ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2) +{ + this->ir_type = ir_type_expression; + + this->operation = ir_expression_operation(op); + this->operands[0] = op0; + this->operands[1] = op1; + this->operands[2] = op2; + this->operands[3] = NULL; + + assert(op > ir_last_binop); + + switch (this->operation) { + case ir_triop_cond_sel: + this->type = op1->type; + break; + + default: + assert(!"not reached: missing automatic type setup for ir_expression"); + this->type = op0->type; + break; + } +} + unsigned int ir_expression::get_num_operands(ir_expression_operation op) { @@ -519,6 +543,7 @@ static const char *const operator_strs[] = { "vector_extract", "fma", "lrp", + "cond_sel", "bfi", "bitfield_extract", "vector_insert", diff --git a/src/glsl/ir.h b/src/glsl/ir.h index df6a36d..1c55758 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1182,6 +1182,19 @@ enum ir_expression_operation { ir_triop_lrp, /** + * \name Conditional Select + * + * A vector conditional select instruction (like ?:, but operating per- + * component on vectors). + * + * \see lower_instructions_visitor::ldexp_to_arith + * \see lower_instructions_visitor::frexp_to_arith + */ + /*@{*/ + ir_triop_cond_sel, + /*@}*/ + + /** * \name Second half of a lowered bitfieldInsert() operation. * * \see lower_instructions::bitfield_insert_to_bfm_bfi @@ -1237,6 +1250,11 @@ public: */ ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1); + /** + * Constructor for ternary operation expressions + */ + ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2); + virtual ir_expression *as_expression() { return this; diff --git a/src/glsl/ir_builder.cpp b/src/glsl/ir_builder.cpp index 7d9cf5e..1f05f84 100644 --- a/src/glsl/ir_builder.cpp +++ b/src/glsl/ir_builder.cpp @@ -173,6 +173,14 @@ expr(ir_expression_operation op, operand a, operand b) return new(mem_ctx) ir_expression(op, a.val, b.val); } +ir_expression * +expr(ir_expression_operation op, operand a, operand b, operand c) +{ + void *mem_ctx = ralloc_parent(a.val); + + return new(mem_ctx) ir_expression(op, a.val, b.val, c.val); +} + ir_expression *add(operand a, operand b) { return expr(ir_binop_add, a, b); @@ -381,6 +389,12 @@ b2i(operand a) return expr(ir_unop_b2i, a); } +ir_expression * +cond_sel(operand a, operand b, operand c) +{ + return expr(ir_triop_cond_sel, a, b, c); +} + ir_if* if_tree(operand condition, ir_instruction *then_branch) diff --git a/src/glsl/ir_builder.h b/src/glsl/ir_builder.h index 7049476..01f7d18 100644 --- a/src/glsl/ir_builder.h +++ b/src/glsl/ir_builder.h @@ -165,6 +165,8 @@ ir_expression *u2i(operand a); ir_expression *b2i(operand a); ir_expression *i2b(operand a); +ir_expression *cond_sel(operand a, operand b, operand c); + /** * Swizzle away later components, but preserve the ordering. */ diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 539e032..8beb7fc 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -396,6 +396,7 @@ ir_expression::constant_expression_value(struct hash_table *variable_context) case ir_binop_rshift: case ir_binop_ldexp: case ir_binop_vector_extract: + case ir_triop_cond_sel: case ir_triop_bitfield_extract: break; @@ -1398,6 +1399,13 @@ ir_expression::constant_expression_value(struct hash_table *variable_context) break; } + case ir_triop_cond_sel: + for (unsigned c = 0; c < components; c++) { + data.u[c] = op[0]->value.b[c] ? op[1]->value.u[c] + : op[2]->value.u[c]; + } + break; + case ir_triop_vector_insert: { const unsigned idx = op[2]->value.u[0]; diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 0244519..61b5e2c 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -538,6 +538,13 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type); break; + case ir_triop_cond_sel: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); + assert(ir->type->vector_elements == ir->operands[0]->type->vector_elements); + assert(ir->type == ir->operands[1]->type); + assert(ir->type == ir->operands[2]->type); + break; + case ir_triop_bfi: assert(ir->operands[0]->type->is_integer()); assert(ir->operands[1]->type == ir->operands[2]->type); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 4675a1e..f50e2c9 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -1499,6 +1499,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir) case ir_quadop_bitfield_insert: case ir_binop_frexp: case ir_binop_ldexp: + case ir_triop_cond_sel: assert(!"not supported"); break; diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 4dd2cc5..88d4ab8 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -1981,6 +1981,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_triop_vector_insert: case ir_binop_frexp: case ir_binop_ldexp: + case ir_triop_cond_sel: /* This operation is not supported, or should have already been handled. */ assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()"); -- 1.8.3.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev