diff options
author | Kenneth Graunke <[email protected]> | 2016-01-14 23:27:03 -0800 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2016-01-15 17:53:44 -0800 |
commit | d54a70aa18a0139a5eefbc5193fabaf739317533 (patch) | |
tree | a39030390a733694b8a3345bb435a3829e5c1db4 /src | |
parent | 61b0cfd84ee6fb1273928ee2c8751301ae805eaa (diff) |
glsl: Allow implicit int -> uint conversions for bitwise operators (&, ^, |).
The ARB has decided that implicit conversions should be performed for
bitwise operators in future language revisions. Implementations of
current language revisions may or may not perform them.
This patch makes Mesa apply implicti conversions even on current
language versions. Applications appear to expect this behavior,
and there's really no downside to doing so.
Fixes shader compilation in Shadow of Mordor.
Bugzilla: https://www.khronos.org/bugzilla/show_bug.cgi?id=1405
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
Reviewed-by: Timothy Arceri <[email protected]>
Cc: [email protected]
Diffstat (limited to 'src')
-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 = |