* 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;
}
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()
{
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
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)
{
/**
* 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
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()
{
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)
{
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()
{
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()
{
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()
{
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
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()
{
#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
}
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;
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;
}
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;
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 } };
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.
*/
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);
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();
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;
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)
/* 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;