diff options
author | Eric Anholt <eric@anholt.net> | 2010-04-06 10:30:54 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-04-06 11:42:34 -0700 |
commit | 326c676236e6a3c90db63e4d0c893aa4f9c21876 (patch) | |
tree | b3513c8d9bb5c0cd596b8d3486edb69136e955f8 | |
parent | 3fff009af169313fa22996d93ad195cf12729763 (diff) |
Handle constant expressions using derefs of const values.
Fixes CorrectParse1.frag and makes for a ton of folding in
CorrectParse2.frag.
-rw-r--r-- | ast_to_hir.cpp | 7 | ||||
-rw-r--r-- | ir.cpp | 1 | ||||
-rw-r--r-- | ir.h | 5 | ||||
-rw-r--r-- | ir_constant_expression.cpp | 9 |
4 files changed, 19 insertions, 3 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 9d067be02d..ddeab8db67 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -1603,12 +1603,15 @@ ast_declarator_list::hir(exec_list *instructions, * declaration. */ if (this->type->qualifier.constant) { - rhs = rhs->constant_expression_value(); - if (!rhs) { + ir_constant *constant_value = rhs->constant_expression_value(); + if (!constant_value) { _mesa_glsl_error(& initializer_loc, state, "initializer of const variable `%s' must be a " "constant expression", decl->identifier); + } else { + rhs = constant_value; + var->constant_value = constant_value; } } @@ -338,6 +338,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name) { this->type = type; this->name = name; + this->constant_value = NULL; if (type && type->base_type == GLSL_TYPE_SAMPLER) this->read_only = true; @@ -154,6 +154,11 @@ public: * equality). This flag enables this behavior. */ unsigned array_lvalue:1; + + /** + * Value assigned in the initializer of a variable declared "const" + */ + ir_constant *constant_value; }; diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp index 6325df5cc7..9c98ceb66c 100644 --- a/ir_constant_expression.cpp +++ b/ir_constant_expression.cpp @@ -395,8 +395,15 @@ ir_constant_visitor::visit(ir_swizzle *ir) void ir_constant_visitor::visit(ir_dereference *ir) { - (void) ir; value = NULL; + + if (ir->mode == ir_dereference::ir_reference_variable) { + ir_variable *var = ir->var->as_variable(); + if (var && var->constant_value) { + value = new ir_constant(ir->type, &var->constant_value->value); + } + } + /* FINISHME: Other dereference modes. */ } |