glsl: introduce ir_binop_all_equal and ir_binop_any_equal, allow vector cmps

Currently GLSL IR forbids any vector comparisons, and defines "ir_binop_equal"
and "ir_binop_nequal" to compare all elements and give a single bool.

This is highly unintuitive and prevents generation of optimal Mesa IR.

Hence, first rename "ir_binop_equal" to "ir_binop_all_equal" and
"ir_binop_nequal" to "ir_binop_any_nequal".

Second, readd "ir_binop_equal" and "ir_binop_nequal" with the same semantics
as less, lequal, etc.

Third, allow all comparisons to acts on vectors.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Luca Barbieri
2010-09-08 01:31:39 +02:00
committed by Ian Romanick
parent 2cdbced10d
commit 4dfb89904c
8 changed files with 76 additions and 25 deletions

View File

@@ -89,9 +89,9 @@ ir_expression::constant_expression_value()
if (op[0]->type->is_array()) {
assert(op[1] != NULL && op[1]->type->is_array());
switch (this->operation) {
case ir_binop_equal:
case ir_binop_all_equal:
return new(ctx) ir_constant(op[0]->has_value(op[1]));
case ir_binop_nequal:
case ir_binop_any_nequal:
return new(ctx) ir_constant(!op[0]->has_value(op[1]));
default:
break;
@@ -622,11 +622,41 @@ ir_expression::constant_expression_value()
assert(0);
}
break;
case ir_binop_equal:
data.b[0] = op[0]->has_value(op[1]);
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] == op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] == op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] == op[1]->value.f[0];
break;
default:
assert(0);
}
break;
case ir_binop_nequal:
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] != op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] != op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] != op[1]->value.f[0];
break;
default:
assert(0);
}
break;
case ir_binop_all_equal:
data.b[0] = op[0]->has_value(op[1]);
break;
case ir_binop_any_nequal:
data.b[0] = !op[0]->has_value(op[1]);
break;