The previous any() implementation would generate arg0.x || arg0.y || arg0.z. Having an expression operation for this makes it easy for the backend to generate something easier (DPn + SNE for 915 FS, .any predication on 965 VS)tags/mesa-7.9-rc1
| @@ -180,6 +180,7 @@ ir.h (new enum) | |||
| ir.cpp:get_num_operands() (used for ir_reader) | |||
| ir.cpp:operator_strs (used for ir_reader) | |||
| ir_constant_expression.cpp (you probably want to be able to constant fold) | |||
| ir_validate.cpp (check users have the right types) | |||
| You may also need to update the backends if they will see the new expr type: | |||
| @@ -2,15 +2,15 @@ | |||
| (signature bool | |||
| (parameters | |||
| (declare (in) bvec2 arg0)) | |||
| ((return (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0)))))) | |||
| ((return (expression bool any (var_ref arg0))))) | |||
| (signature bool | |||
| (parameters | |||
| (declare (in) bvec3 arg0)) | |||
| ((return (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0)))))) | |||
| ((return (expression bool any (var_ref arg0))))) | |||
| (signature bool | |||
| (parameters | |||
| (declare (in) bvec4 arg0)) | |||
| ((return (expression bool || (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0)))))) | |||
| ((return (expression bool any (var_ref arg0))))) | |||
| )) | |||
| @@ -184,6 +184,7 @@ ir_expression::get_num_operands(ir_expression_operation op) | |||
| 1, /* ir_unop_i2b */ | |||
| 1, /* ir_unop_b2i */ | |||
| 1, /* ir_unop_u2f */ | |||
| 1, /* ir_unop_any */ | |||
| 1, /* ir_unop_trunc */ | |||
| 1, /* ir_unop_ceil */ | |||
| @@ -252,6 +253,7 @@ static const char *const operator_strs[] = { | |||
| "i2b", | |||
| "b2i", | |||
| "u2f", | |||
| "any", | |||
| "trunc", | |||
| "ceil", | |||
| "floor", | |||
| @@ -604,6 +604,7 @@ enum ir_expression_operation { | |||
| ir_unop_i2b, /**< int-to-boolean conversion */ | |||
| ir_unop_b2i, /**< Boolean-to-int conversion */ | |||
| ir_unop_u2f, /**< Unsigned-to-float conversion. */ | |||
| ir_unop_any, | |||
| /** | |||
| * \name Unary floating-point rounding operations. | |||
| @@ -149,6 +149,15 @@ ir_expression::constant_expression_value() | |||
| } | |||
| break; | |||
| case ir_unop_any: | |||
| assert(op[0]->type->is_boolean()); | |||
| data.b[0] = false; | |||
| for (unsigned c = 0; c < op[0]->type->components(); c++) { | |||
| if (op[0]->value.b[c]) | |||
| data.b[0] = true; | |||
| } | |||
| break; | |||
| case ir_unop_trunc: | |||
| assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); | |||
| for (unsigned c = 0; c < op[0]->type->components(); c++) { | |||
| @@ -223,6 +223,11 @@ ir_validate::visit_leave(ir_expression *ir) | |||
| assert(ir->type->base_type == GLSL_TYPE_FLOAT); | |||
| break; | |||
| case ir_unop_any: | |||
| assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); | |||
| assert(ir->type == glsl_type::bool_type); | |||
| break; | |||
| case ir_unop_trunc: | |||
| case ir_unop_ceil: | |||
| case ir_unop_floor: | |||
| @@ -844,6 +844,26 @@ ir_to_mesa_visitor::visit(ir_expression *ir) | |||
| ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); | |||
| } | |||
| break; | |||
| case ir_unop_any: | |||
| switch (ir->operands[0]->type->vector_elements) { | |||
| case 4: | |||
| ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, op[0], op[0]); | |||
| break; | |||
| case 3: | |||
| ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, op[0], op[0]); | |||
| break; | |||
| case 2: | |||
| ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, op[0], op[0]); | |||
| break; | |||
| default: | |||
| assert(!"unreached: ir_unop_any of non-bvec"); | |||
| break; | |||
| } | |||
| ir_to_mesa_emit_op2(ir, OPCODE_SNE, | |||
| result_dst, result_src, src_reg_for_float(0.0)); | |||
| break; | |||
| case ir_binop_logic_xor: | |||
| ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); | |||
| break; | |||