summaryrefslogtreecommitdiff
path: root/ast_to_hir.cpp
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-05-19 10:38:37 -0700
committerEric Anholt <eric@anholt.net>2010-06-01 15:15:04 -0700
commit336b4ad8c76a525a0df2f4b0fc1d67e86bc5db3f (patch)
tree14a9aa33b2f0e378fcaf59a242726a91c0b13c3e /ast_to_hir.cpp
parent60fa1a9458b012f39919a9c4070bfc4a0654d317 (diff)
Handle GLSL 1.20 implicit type conversions.
We were nicely constructing a new expression for the implicit type conversion, but then checking that the previous types matched instead of the new expression's type. Fixes errors in Regnum Online shaders.
Diffstat (limited to 'ast_to_hir.cpp')
-rw-r--r--ast_to_hir.cpp29
1 files changed, 20 insertions, 9 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index 7759c36..8945bce 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -132,8 +132,8 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
bool multiply,
struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
- const glsl_type *const type_a = value_a->type;
- const glsl_type *const type_b = value_b->type;
+ const glsl_type *type_a = value_a->type;
+ const glsl_type *type_b = value_b->type;
/* From GLSL 1.50 spec, page 56:
*
@@ -159,7 +159,9 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
"arithmetic operator");
return glsl_type::error_type;
}
-
+ type_a = value_a->type;
+ type_b = value_b->type;
+
/* "If the operands are integer types, they must both be signed or
* both be unsigned."
*
@@ -362,8 +364,8 @@ static const struct glsl_type *
relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
- const glsl_type *const type_a = value_a->type;
- const glsl_type *const type_b = value_b->type;
+ const glsl_type *type_a = value_a->type;
+ const glsl_type *type_b = value_b->type;
/* From GLSL 1.50 spec, page 56:
* "The relational operators greater than (>), less than (<), greater
@@ -391,6 +393,8 @@ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
"relational operator");
return glsl_type::error_type;
}
+ type_a = value_a->type;
+ type_b = value_b->type;
if (type_a->base_type != type_b->base_type) {
_mesa_glsl_error(loc, state, "base type mismatch");
@@ -420,9 +424,10 @@ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
* type-check return values.
*/
ir_rvalue *
-validate_assignment(const glsl_type *lhs_type, ir_rvalue *rhs)
+validate_assignment(struct _mesa_glsl_parse_state *state,
+ const glsl_type *lhs_type, ir_rvalue *rhs)
{
- const glsl_type *const rhs_type = rhs->type;
+ const glsl_type *rhs_type = rhs->type;
/* If there is already some error in the RHS, just return it. Anything
* else will lead to an avalanche of error message back to the user.
@@ -447,7 +452,13 @@ validate_assignment(const glsl_type *lhs_type, ir_rvalue *rhs)
return rhs;
}
- /* FINISHME: Check for and apply automatic conversions. */
+ /* Check for implicit conversion in GLSL 1.20 */
+ if (apply_implicit_conversion(lhs_type, rhs, state)) {
+ rhs_type = rhs->type;
+ if (rhs_type == lhs_type)
+ return rhs;
+ }
+
return NULL;
}
@@ -466,7 +477,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
}
}
- ir_rvalue *new_rhs = validate_assignment(lhs->type, rhs);
+ ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs);
if (new_rhs == NULL) {
_mesa_glsl_error(& lhs_loc, state, "type mismatch");
} else {