summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-01-14 23:27:03 -0800
committerKenneth Graunke <[email protected]>2016-01-15 17:53:44 -0800
commitd54a70aa18a0139a5eefbc5193fabaf739317533 (patch)
treea39030390a733694b8a3345bb435a3829e5c1db4
parent61b0cfd84ee6fb1273928ee2c8751301ae805eaa (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]
-rw-r--r--src/glsl/ast_to_hir.cpp46
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 =