summaryrefslogtreecommitdiffstats
path: root/src/glsl/ast_to_hir.cpp
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2011-10-31 18:22:48 -0700
committerPaul Berry <[email protected]>2011-11-02 09:28:54 -0700
commit9abda92b270596fd3a5e2e8b74e3fc3255da70ce (patch)
tree6860a505226509221acd9fe6316486de2ae8f134 /src/glsl/ast_to_hir.cpp
parenta0d8e5d12a059fcb5e606c262d30e41ad6248282 (diff)
glsl: Fix type mismatch when incrementing or decrementing uint.
When converting an expression like "++x" to GLSL IR we were failing to account for the possibility that x might be an unsigned integral type. As a result the user would receive a bogus error message "Could not implicitly convert operands to arithmetic operator". Fixes piglit tests {vs,fs}-{increment,decrement}-uint. Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl/ast_to_hir.cpp')
-rw-r--r--src/glsl/ast_to_hir.cpp32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 7584fdf8c67..ebdbbc10e69 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -935,6 +935,28 @@ check_builtin_array_max_size(const char *name, unsigned size,
return false;
}
+/**
+ * Create the constant 1, of a which is appropriate for incrementing and
+ * decrementing values of the given GLSL type. For example, if type is vec4,
+ * this creates a constant value of 1.0 having type float.
+ *
+ * If the given type is invalid for increment and decrement operators, return
+ * a floating point 1--the error will be detected later.
+ */
+static ir_rvalue *
+constant_one_for_inc_dec(void *ctx, const glsl_type *type)
+{
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ return new(ctx) ir_constant((unsigned) 1);
+ case GLSL_TYPE_INT:
+ return new(ctx) ir_constant(1);
+ default:
+ case GLSL_TYPE_FLOAT:
+ return new(ctx) ir_constant(1.0f);
+ }
+}
+
ir_rvalue *
ast_expression::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
@@ -1442,10 +1464,7 @@ ast_expression::hir(exec_list *instructions,
case ast_pre_inc:
case ast_pre_dec: {
op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
+ op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
type = arithmetic_result_type(op[0], op[1], false, state, & loc);
@@ -1463,10 +1482,7 @@ ast_expression::hir(exec_list *instructions,
case ast_post_inc:
case ast_post_dec: {
op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
+ op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
error_emitted = op[0]->type->is_error() || op[1]->type->is_error();