diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/ast_function.cpp | 2 | ||||
-rw-r--r-- | src/glsl/ir.h | 31 | ||||
-rw-r--r-- | src/glsl/ir_constant_expression.cpp | 42 |
3 files changed, 44 insertions, 31 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 58cf6854b85..9e7c5995fc9 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -278,7 +278,7 @@ generate_call(exec_list *instructions, ir_function_signature *sig, * Function calls were first allowed to be constant expressions in GLSL 1.20. */ if (state->language_version >= 120) { - ir_constant *value = sig->constant_expression_value(actual_parameters); + ir_constant *value = sig->constant_expression_value(actual_parameters, NULL); if (value != NULL) { return value; } diff --git a/src/glsl/ir.h b/src/glsl/ir.h index ddfaf3614ae..d7df41d893c 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -146,7 +146,7 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_rvalue * as_rvalue() { @@ -502,10 +502,11 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); /** - * Attempt to evaluate this function as a constant expression, given - * a list of the actual parameters. Returns NULL for non-built-ins. + * Attempt to evaluate this function as a constant expression, + * given a list of the actual parameters and the variable context. + * Returns NULL for non-built-ins. */ - ir_constant *constant_expression_value(exec_list *actual_parameters); + ir_constant *constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context); /** * Get the name of the function for which this is a signature @@ -763,7 +764,7 @@ public: virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -999,10 +1000,14 @@ public: /** * Attempt to constant-fold the expression * + * The "variable_context" hash table links ir_variable * to ir_constant * + * that represent the variables' values. \c NULL represents an empty + * context. + * * If the expression cannot be constant folded, this method will return * \c NULL. */ - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); /** * Determine the number of operands used by an expression @@ -1065,7 +1070,7 @@ public: virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_call *as_call() { @@ -1297,7 +1302,7 @@ public: virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -1389,7 +1394,7 @@ public: virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_swizzle *as_swizzle() { @@ -1456,7 +1461,7 @@ public: virtual ir_dereference_variable *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_dereference_variable *as_dereference_variable() { @@ -1505,7 +1510,7 @@ public: virtual ir_dereference_array *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_dereference_array *as_dereference_array() { @@ -1544,7 +1549,7 @@ public: virtual ir_dereference_record *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); /** * Get the variable that is ultimately referenced by an r-value @@ -1609,7 +1614,7 @@ public: virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_constant *as_constant() { diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index e724e3a5dda..bf4bb319e8b 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -38,6 +38,7 @@ #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" +#include "program/hash_table.h" /* Using C99 rounding functions for roundToEven() implementation is * difficult, because round(), rint, and nearbyint() are affected by @@ -71,14 +72,14 @@ dot(ir_constant *op0, ir_constant *op1) } ir_constant * -ir_rvalue::constant_expression_value() +ir_rvalue::constant_expression_value(struct hash_table *variable_context) { assert(this->type->is_error()); return NULL; } ir_constant * -ir_expression::constant_expression_value() +ir_expression::constant_expression_value(struct hash_table *variable_context) { if (this->type->is_error()) return NULL; @@ -89,7 +90,7 @@ ir_expression::constant_expression_value() memset(&data, 0, sizeof(data)); for (unsigned operand = 0; operand < this->get_num_operands(); operand++) { - op[operand] = this->operands[operand]->constant_expression_value(); + op[operand] = this->operands[operand]->constant_expression_value(variable_context); if (!op[operand]) return NULL; } @@ -886,7 +887,7 @@ ir_expression::constant_expression_value() ir_constant * -ir_texture::constant_expression_value() +ir_texture::constant_expression_value(struct hash_table *variable_context) { /* texture lookups aren't constant expressions */ return NULL; @@ -894,9 +895,9 @@ ir_texture::constant_expression_value() ir_constant * -ir_swizzle::constant_expression_value() +ir_swizzle::constant_expression_value(struct hash_table *variable_context) { - ir_constant *v = this->val->constant_expression_value(); + ir_constant *v = this->val->constant_expression_value(variable_context); if (v != NULL) { ir_constant_data data = { { 0 } }; @@ -923,12 +924,19 @@ ir_swizzle::constant_expression_value() ir_constant * -ir_dereference_variable::constant_expression_value() +ir_dereference_variable::constant_expression_value(struct hash_table *variable_context) { /* This may occur during compile and var->type is glsl_type::error_type */ if (!var) return NULL; + /* Give priority to the context hashtable, if it exists */ + if (variable_context) { + ir_constant *value = (ir_constant *)hash_table_find(variable_context, var); + if(value) + return value; + } + /* The constant_value of a uniform variable is its initializer, * not the lifetime constant value of the uniform. */ @@ -943,10 +951,10 @@ ir_dereference_variable::constant_expression_value() ir_constant * -ir_dereference_array::constant_expression_value() +ir_dereference_array::constant_expression_value(struct hash_table *variable_context) { - ir_constant *array = this->array->constant_expression_value(); - ir_constant *idx = this->array_index->constant_expression_value(); + ir_constant *array = this->array->constant_expression_value(variable_context); + ir_constant *idx = this->array_index->constant_expression_value(variable_context); if ((array != NULL) && (idx != NULL)) { void *ctx = ralloc_parent(this); @@ -998,7 +1006,7 @@ ir_dereference_array::constant_expression_value() ir_constant * -ir_dereference_record::constant_expression_value() +ir_dereference_record::constant_expression_value(struct hash_table *variable_context) { ir_constant *v = this->record->constant_expression_value(); @@ -1007,7 +1015,7 @@ ir_dereference_record::constant_expression_value() ir_constant * -ir_assignment::constant_expression_value() +ir_assignment::constant_expression_value(struct hash_table *variable_context) { /* FINISHME: Handle CEs involving assignment (return RHS) */ return NULL; @@ -1015,21 +1023,21 @@ ir_assignment::constant_expression_value() ir_constant * -ir_constant::constant_expression_value() +ir_constant::constant_expression_value(struct hash_table *variable_context) { return this; } ir_constant * -ir_call::constant_expression_value() +ir_call::constant_expression_value(struct hash_table *variable_context) { - return this->callee->constant_expression_value(&this->actual_parameters); + return this->callee->constant_expression_value(&this->actual_parameters, variable_context); } ir_constant * -ir_function_signature::constant_expression_value(exec_list *actual_parameters) +ir_function_signature::constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context) { const glsl_type *type = this->return_type; if (type == glsl_type::void_type) @@ -1047,7 +1055,7 @@ ir_function_signature::constant_expression_value(exec_list *actual_parameters) /* Check if all parameters are constant */ ir_constant *op[3]; foreach_list(n, actual_parameters) { - ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(); + ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(variable_context); if (constant == NULL) return NULL; |