Module: Mesa Branch: shader-work Commit: 4b7392ae4856f7e602e8b5eda907497ab9953433 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4b7392ae4856f7e602e8b5eda907497ab9953433
Author: Luca Barbieri <[email protected]> Date: Wed Sep 8 01:31:39 2010 +0200 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. --- src/glsl/ast_to_hir.cpp | 4 +- src/glsl/ir.cpp | 2 + src/glsl/ir.h | 6 +++- src/glsl/ir_algebraic.cpp | 2 + src/glsl/ir_constant_expression.cpp | 38 +++++++++++++++++++++++++++++++--- src/glsl/ir_mat_op_to_vec.cpp | 6 ++-- src/glsl/ir_validate.cpp | 25 +++++++++++------------ src/mesa/program/ir_to_mesa.cpp | 8 ++++++- 8 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 762f802..6a1e984 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -628,8 +628,8 @@ ast_expression::hir(exec_list *instructions, ir_binop_greater, ir_binop_lequal, ir_binop_gequal, - ir_binop_equal, - ir_binop_nequal, + ir_binop_all_equal, + ir_binop_any_nequal, ir_binop_bit_and, ir_binop_bit_xor, ir_binop_bit_or, diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 6d72725..11ede27 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -208,6 +208,8 @@ ir_expression::get_num_operands(ir_expression_operation op) 2, /* ir_binop_gequal */ 2, /* ir_binop_equal */ 2, /* ir_binop_nequal */ + 2, /* ir_binop_all_equal */ + 2, /* ir_binop_any_nequal */ 2, /* ir_binop_lshift */ 2, /* ir_binop_rshift */ diff --git a/src/glsl/ir.h b/src/glsl/ir.h index efe59d8..7ffb6b3 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -670,16 +670,18 @@ enum ir_expression_operation { ir_binop_greater, ir_binop_lequal, ir_binop_gequal, + ir_binop_equal, + ir_binop_nequal, /** * Returns single boolean for whether all components of operands[0] * equal the components of operands[1]. */ - ir_binop_equal, + ir_binop_all_equal, /** * Returns single boolean for whether any component of operands[0] * is not equal to the corresponding component of operands[1]. */ - ir_binop_nequal, + ir_binop_any_nequal, /*...@}*/ /** diff --git a/src/glsl/ir_algebraic.cpp b/src/glsl/ir_algebraic.cpp index ff81563..2ed66db 100644 --- a/src/glsl/ir_algebraic.cpp +++ b/src/glsl/ir_algebraic.cpp @@ -270,6 +270,8 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) case ir_binop_gequal: new_op = ir_binop_less; break; case ir_binop_equal: new_op = ir_binop_nequal; break; case ir_binop_nequal: new_op = ir_binop_equal; break; + case ir_binop_all_equal: new_op = ir_binop_any_nequal; break; + case ir_binop_any_nequal: new_op = ir_binop_all_equal; break; default: /* The default case handler is here to silence a warning from GCC. diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 458dca7..7de8b0a 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -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; diff --git a/src/glsl/ir_mat_op_to_vec.cpp b/src/glsl/ir_mat_op_to_vec.cpp index da6de94..2b5402a 100644 --- a/src/glsl/ir_mat_op_to_vec.cpp +++ b/src/glsl/ir_mat_op_to_vec.cpp @@ -473,10 +473,10 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) } break; - case ir_binop_equal: - case ir_binop_nequal: + case ir_binop_all_equal: + case ir_binop_any_nequal: do_equal_mat_mat(result_var, op_var[1], op_var[0], - (orig_expr->operation == ir_binop_equal)); + (orig_expr->operation == ir_binop_all_equal)); break; default: diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 8e82590..b3ea566 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -283,6 +283,16 @@ ir_validate::visit_leave(ir_expression *ir) case ir_binop_min: case ir_binop_max: case ir_binop_pow: + case ir_binop_less: + case ir_binop_greater: + case ir_binop_lequal: + case ir_binop_gequal: + case ir_binop_equal: + case ir_binop_nequal: + /* GLSL < > <= >= operators take scalar floats/ints, but in the + * IR we want to do them for vectors instead to support the + * lessEqual() and friends builtins, and Mesa IR constructs + */ if (ir->operands[0]->type->is_scalar()) assert(ir->operands[1]->type == ir->type); else if (ir->operands[1]->type->is_scalar()) @@ -293,20 +303,9 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[0]->type == ir->type); } break; - case ir_binop_less: - case ir_binop_greater: - case ir_binop_lequal: - case ir_binop_gequal: - /* GLSL < > <= >= operators take scalar floats/ints, but in the - * IR we may want to do them for vectors instead to support the - * lessEqual() and friends builtins. - */ - assert(ir->type == glsl_type::bool_type); - assert(ir->operands[0]->type == ir->operands[1]->type); - break; - case ir_binop_equal: - case ir_binop_nequal: + case ir_binop_all_equal: + case ir_binop_any_nequal: /* GLSL == and != operate on vectors and return a bool, and the * IR matches that. We may want to switch up the IR to work on * vectors and return a bvec and make the operators break down diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 5346d8f..da74ad4 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -852,6 +852,12 @@ ir_to_mesa_visitor::visit(ir_expression *ir) ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); break; case ir_binop_equal: + ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); + break; + case ir_binop_nequal: + ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); + break; + case ir_binop_all_equal: /* "==" operator producing a scalar boolean. */ if (ir->operands[0]->type->is_vector() || ir->operands[1]->type->is_vector()) { @@ -865,7 +871,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir) ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); } break; - case ir_binop_nequal: + case ir_binop_any_nequal: /* "!=" operator producing a scalar boolean. */ if (ir->operands[0]->type->is_vector() || ir->operands[1]->type->is_vector()) { _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
