diff options
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 13696a36b0c..0f51c54bfe3 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -487,15 +487,17 @@ unary_arithmetic_result_type(const struct glsl_type *type, * If the given types to the bit-logic operator are invalid, return * glsl_type::error_type. * - * \param type_a Type of LHS of bit-logic op - * \param type_b Type of RHS of bit-logic op + * \param value_a LHS of bit-logic op + * \param value_b RHS of bit-logic op */ static const struct glsl_type * -bit_logic_result_type(const struct glsl_type *type_a, - const struct glsl_type *type_b, +bit_logic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, ast_operators op, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { + const glsl_type *type_a = value_a->type; + const glsl_type *type_b = value_b->type; + if (!state->check_bitwise_operations_allowed(loc)) { return glsl_type::error_type; } @@ -517,6 +519,36 @@ bit_logic_result_type(const struct glsl_type *type_a, return glsl_type::error_type; } + /* Prior to GLSL 4.0 / GL_ARB_gpu_shader5, implicit conversions didn't + * make sense for bitwise operations, as they don't operate on floats. + * + * GLSL 4.0 added implicit int -> uint conversions, which are relevant + * here. It wasn't clear whether or not we should apply them to bitwise + * operations. However, Khronos has decided that they should in future + * language revisions. Applications also rely on this behavior. We opt + * to apply them in general, but issue a portability warning. + * + * See https://www.khronos.org/bugzilla/show_bug.cgi?id=1405 + */ + if (type_a->base_type != type_b->base_type) { + if (!apply_implicit_conversion(type_a, value_b, state) + && !apply_implicit_conversion(type_b, value_a, state)) { + _mesa_glsl_error(loc, state, + "could not implicitly convert operands to " + "`%s` operator", + ast_expression::operator_string(op)); + return glsl_type::error_type; + } else { + _mesa_glsl_warning(loc, state, + "some implementations may not support implicit " + "int -> uint conversions for `%s' operators; " + "consider casting explicitly for portability", + ast_expression::operator_string(op)); + } + type_a = value_a->type; + type_b = value_b->type; + } + /* "The fundamental types of the operands (signed or unsigned) must * match," */ @@ -1434,8 +1466,7 @@ ast_expression::do_hir(exec_list *instructions, case ast_bit_or: op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); - type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper, - state, &loc); + type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc); result = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); @@ -1625,8 +1656,7 @@ ast_expression::do_hir(exec_list *instructions, case ast_or_assign: { op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); - type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper, - state, &loc); + type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc); ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = |