mesa: Add new ir_unop_any() expression operation.

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)
This commit is contained in:
Eric Anholt
2010-08-23 12:21:33 -07:00
parent 47003a8f65
commit 5e9ac94cc4
7 changed files with 41 additions and 3 deletions

View File

@@ -180,6 +180,7 @@ ir.h (new enum)
ir.cpp:get_num_operands() (used for ir_reader) ir.cpp:get_num_operands() (used for ir_reader)
ir.cpp:operator_strs (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_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: You may also need to update the backends if they will see the new expr type:

View File

@@ -2,15 +2,15 @@
(signature bool (signature bool
(parameters (parameters
(declare (in) bvec2 arg0)) (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 (signature bool
(parameters (parameters
(declare (in) bvec3 arg0)) (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 (signature bool
(parameters (parameters
(declare (in) bvec4 arg0)) (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)))))
)) ))

View File

@@ -184,6 +184,7 @@ ir_expression::get_num_operands(ir_expression_operation op)
1, /* ir_unop_i2b */ 1, /* ir_unop_i2b */
1, /* ir_unop_b2i */ 1, /* ir_unop_b2i */
1, /* ir_unop_u2f */ 1, /* ir_unop_u2f */
1, /* ir_unop_any */
1, /* ir_unop_trunc */ 1, /* ir_unop_trunc */
1, /* ir_unop_ceil */ 1, /* ir_unop_ceil */
@@ -252,6 +253,7 @@ static const char *const operator_strs[] = {
"i2b", "i2b",
"b2i", "b2i",
"u2f", "u2f",
"any",
"trunc", "trunc",
"ceil", "ceil",
"floor", "floor",

View File

@@ -604,6 +604,7 @@ enum ir_expression_operation {
ir_unop_i2b, /**< int-to-boolean conversion */ ir_unop_i2b, /**< int-to-boolean conversion */
ir_unop_b2i, /**< Boolean-to-int conversion */ ir_unop_b2i, /**< Boolean-to-int conversion */
ir_unop_u2f, /**< Unsigned-to-float conversion. */ ir_unop_u2f, /**< Unsigned-to-float conversion. */
ir_unop_any,
/** /**
* \name Unary floating-point rounding operations. * \name Unary floating-point rounding operations.

View File

@@ -149,6 +149,15 @@ ir_expression::constant_expression_value()
} }
break; 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: case ir_unop_trunc:
assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
for (unsigned c = 0; c < op[0]->type->components(); c++) { for (unsigned c = 0; c < op[0]->type->components(); c++) {

View File

@@ -223,6 +223,11 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->type->base_type == GLSL_TYPE_FLOAT); assert(ir->type->base_type == GLSL_TYPE_FLOAT);
break; 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_trunc:
case ir_unop_ceil: case ir_unop_ceil:
case ir_unop_floor: case ir_unop_floor:

View File

@@ -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]); ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
} }
break; 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: case ir_binop_logic_xor:
ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
break; break;