glsl: Add a variable context to constant_expression_value().
Signed-off-by: Olivier Galibert <galibert@pobox.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net> [v1]
This commit is contained in:

committed by
Kenneth Graunke

parent
27a198388e
commit
6e4852a3a5
@@ -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.
|
* Function calls were first allowed to be constant expressions in GLSL 1.20.
|
||||||
*/
|
*/
|
||||||
if (state->language_version >= 120) {
|
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) {
|
if (value != NULL) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@@ -146,7 +146,7 @@ public:
|
|||||||
|
|
||||||
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
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_rvalue * as_rvalue()
|
||||||
{
|
{
|
||||||
@@ -502,10 +502,11 @@ public:
|
|||||||
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to evaluate this function as a constant expression, given
|
* Attempt to evaluate this function as a constant expression,
|
||||||
* a list of the actual parameters. Returns NULL for non-built-ins.
|
* 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
|
* 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_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)
|
virtual void accept(ir_visitor *v)
|
||||||
{
|
{
|
||||||
@@ -999,10 +1000,14 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Attempt to constant-fold the expression
|
* 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
|
* If the expression cannot be constant folded, this method will return
|
||||||
* \c NULL.
|
* \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
|
* 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_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_call *as_call()
|
||||||
{
|
{
|
||||||
@@ -1297,7 +1302,7 @@ public:
|
|||||||
|
|
||||||
virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
|
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 void accept(ir_visitor *v)
|
||||||
{
|
{
|
||||||
@@ -1389,7 +1394,7 @@ public:
|
|||||||
|
|
||||||
virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
|
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_swizzle *as_swizzle()
|
||||||
{
|
{
|
||||||
@@ -1456,7 +1461,7 @@ public:
|
|||||||
virtual ir_dereference_variable *clone(void *mem_ctx,
|
virtual ir_dereference_variable *clone(void *mem_ctx,
|
||||||
struct hash_table *) const;
|
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_variable *as_dereference_variable()
|
||||||
{
|
{
|
||||||
@@ -1505,7 +1510,7 @@ public:
|
|||||||
virtual ir_dereference_array *clone(void *mem_ctx,
|
virtual ir_dereference_array *clone(void *mem_ctx,
|
||||||
struct hash_table *) const;
|
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_array *as_dereference_array()
|
||||||
{
|
{
|
||||||
@@ -1544,7 +1549,7 @@ public:
|
|||||||
virtual ir_dereference_record *clone(void *mem_ctx,
|
virtual ir_dereference_record *clone(void *mem_ctx,
|
||||||
struct hash_table *) const;
|
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
|
* 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 *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()
|
virtual ir_constant *as_constant()
|
||||||
{
|
{
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
#include "ir.h"
|
#include "ir.h"
|
||||||
#include "ir_visitor.h"
|
#include "ir_visitor.h"
|
||||||
#include "glsl_types.h"
|
#include "glsl_types.h"
|
||||||
|
#include "program/hash_table.h"
|
||||||
|
|
||||||
/* Using C99 rounding functions for roundToEven() implementation is
|
/* Using C99 rounding functions for roundToEven() implementation is
|
||||||
* difficult, because round(), rint, and nearbyint() are affected by
|
* difficult, because round(), rint, and nearbyint() are affected by
|
||||||
@@ -71,14 +72,14 @@ dot(ir_constant *op0, ir_constant *op1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ir_constant *
|
ir_constant *
|
||||||
ir_rvalue::constant_expression_value()
|
ir_rvalue::constant_expression_value(struct hash_table *variable_context)
|
||||||
{
|
{
|
||||||
assert(this->type->is_error());
|
assert(this->type->is_error());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_constant *
|
ir_constant *
|
||||||
ir_expression::constant_expression_value()
|
ir_expression::constant_expression_value(struct hash_table *variable_context)
|
||||||
{
|
{
|
||||||
if (this->type->is_error())
|
if (this->type->is_error())
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -89,7 +90,7 @@ ir_expression::constant_expression_value()
|
|||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
|
|
||||||
for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
|
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])
|
if (!op[operand])
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -886,7 +887,7 @@ ir_expression::constant_expression_value()
|
|||||||
|
|
||||||
|
|
||||||
ir_constant *
|
ir_constant *
|
||||||
ir_texture::constant_expression_value()
|
ir_texture::constant_expression_value(struct hash_table *variable_context)
|
||||||
{
|
{
|
||||||
/* texture lookups aren't constant expressions */
|
/* texture lookups aren't constant expressions */
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -894,9 +895,9 @@ ir_texture::constant_expression_value()
|
|||||||
|
|
||||||
|
|
||||||
ir_constant *
|
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) {
|
if (v != NULL) {
|
||||||
ir_constant_data data = { { 0 } };
|
ir_constant_data data = { { 0 } };
|
||||||
@@ -923,12 +924,19 @@ ir_swizzle::constant_expression_value()
|
|||||||
|
|
||||||
|
|
||||||
ir_constant *
|
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 */
|
/* This may occur during compile and var->type is glsl_type::error_type */
|
||||||
if (!var)
|
if (!var)
|
||||||
return NULL;
|
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,
|
/* The constant_value of a uniform variable is its initializer,
|
||||||
* not the lifetime constant value of the uniform.
|
* not the lifetime constant value of the uniform.
|
||||||
*/
|
*/
|
||||||
@@ -943,10 +951,10 @@ ir_dereference_variable::constant_expression_value()
|
|||||||
|
|
||||||
|
|
||||||
ir_constant *
|
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 *array = this->array->constant_expression_value(variable_context);
|
||||||
ir_constant *idx = this->array_index->constant_expression_value();
|
ir_constant *idx = this->array_index->constant_expression_value(variable_context);
|
||||||
|
|
||||||
if ((array != NULL) && (idx != NULL)) {
|
if ((array != NULL) && (idx != NULL)) {
|
||||||
void *ctx = ralloc_parent(this);
|
void *ctx = ralloc_parent(this);
|
||||||
@@ -998,7 +1006,7 @@ ir_dereference_array::constant_expression_value()
|
|||||||
|
|
||||||
|
|
||||||
ir_constant *
|
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 *v = this->record->constant_expression_value();
|
||||||
|
|
||||||
@@ -1007,7 +1015,7 @@ ir_dereference_record::constant_expression_value()
|
|||||||
|
|
||||||
|
|
||||||
ir_constant *
|
ir_constant *
|
||||||
ir_assignment::constant_expression_value()
|
ir_assignment::constant_expression_value(struct hash_table *variable_context)
|
||||||
{
|
{
|
||||||
/* FINISHME: Handle CEs involving assignment (return RHS) */
|
/* FINISHME: Handle CEs involving assignment (return RHS) */
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1015,21 +1023,21 @@ ir_assignment::constant_expression_value()
|
|||||||
|
|
||||||
|
|
||||||
ir_constant *
|
ir_constant *
|
||||||
ir_constant::constant_expression_value()
|
ir_constant::constant_expression_value(struct hash_table *variable_context)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ir_constant *
|
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_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;
|
const glsl_type *type = this->return_type;
|
||||||
if (type == glsl_type::void_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 */
|
/* Check if all parameters are constant */
|
||||||
ir_constant *op[3];
|
ir_constant *op[3];
|
||||||
foreach_list(n, actual_parameters) {
|
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)
|
if (constant == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user