glsl: Add a constant_referenced method to ir_dereference*

The method is used to get a reference to an ir_constant * within the
context of evaluating an assignment when calculating a
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:
Olivier Galibert
2012-05-02 23:11:39 +02:00
committed by Kenneth Graunke
parent 6e4852a3a5
commit a270e86d38
2 changed files with 128 additions and 0 deletions

View File

@@ -1451,6 +1451,15 @@ public:
* Get the variable that is ultimately referenced by an r-value
*/
virtual ir_variable *variable_referenced() const = 0;
/**
* Get the constant that is ultimately referenced by an r-value,
* in a constant expression evaluation context.
*
* The offset is used when the reference is to a specific column of
* a matrix.
*/
virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const = 0;
};
@@ -1476,6 +1485,15 @@ public:
return this->var;
}
/**
* Get the constant that is ultimately referenced by an r-value,
* in a constant expression evaluation context.
*
* The offset is used when the reference is to a specific column of
* a matrix.
*/
virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const;
virtual ir_variable *whole_variable_referenced()
{
/* ir_dereference_variable objects always dereference the entire
@@ -1525,6 +1543,15 @@ public:
return this->array->variable_referenced();
}
/**
* Get the constant that is ultimately referenced by an r-value,
* in a constant expression evaluation context.
*
* The offset is used when the reference is to a specific column of
* a matrix.
*/
virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const;
virtual void accept(ir_visitor *v)
{
v->visit(this);
@@ -1559,6 +1586,15 @@ public:
return this->record->variable_referenced();
}
/**
* Get the constant that is ultimately referenced by an r-value,
* in a constant expression evaluation context.
*
* The offset is used when the reference is to a specific column of
* a matrix.
*/
virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const;
virtual void accept(ir_visitor *v)
{
v->visit(this);

View File

@@ -923,6 +923,19 @@ ir_swizzle::constant_expression_value(struct hash_table *variable_context)
}
void
ir_dereference_variable::constant_referenced(struct hash_table *variable_context,
ir_constant *&store, int &offset) const
{
if (variable_context) {
store = (ir_constant *)hash_table_find(variable_context, var);
offset = 0;
} else {
store = NULL;
offset = 0;
}
}
ir_constant *
ir_dereference_variable::constant_expression_value(struct hash_table *variable_context)
{
@@ -950,6 +963,60 @@ ir_dereference_variable::constant_expression_value(struct hash_table *variable_c
}
void
ir_dereference_array::constant_referenced(struct hash_table *variable_context,
ir_constant *&store, int &offset) const
{
ir_constant *index_c = array_index->constant_expression_value(variable_context);
if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer()) {
store = 0;
offset = 0;
return;
}
int index = index_c->type->base_type == GLSL_TYPE_INT ?
index_c->get_int_component(0) :
index_c->get_uint_component(0);
ir_constant *substore;
int suboffset;
const ir_dereference *deref = array->as_dereference();
if (!deref) {
store = 0;
offset = 0;
return;
}
deref->constant_referenced(variable_context, substore, suboffset);
if (!substore) {
store = 0;
offset = 0;
return;
}
const glsl_type *vt = substore->type;
if (vt->is_array()) {
store = substore->get_array_element(index);
offset = 0;
return;
}
if (vt->is_matrix()) {
store = substore;
offset = index * vt->vector_elements;
return;
}
if (vt->is_vector()) {
store = substore;
offset = suboffset + index;
return;
}
store = 0;
offset = 0;
}
ir_constant *
ir_dereference_array::constant_expression_value(struct hash_table *variable_context)
{
@@ -1005,6 +1072,31 @@ ir_dereference_array::constant_expression_value(struct hash_table *variable_cont
}
void
ir_dereference_record::constant_referenced(struct hash_table *variable_context,
ir_constant *&store, int &offset) const
{
ir_constant *substore;
int suboffset;
const ir_dereference *deref = record->as_dereference();
if (!deref) {
store = 0;
offset = 0;
return;
}
deref->constant_referenced(variable_context, substore, suboffset);
if (!substore) {
store = 0;
offset = 0;
return;
}
store = substore->get_record_field(field);
offset = 0;
}
ir_constant *
ir_dereference_record::constant_expression_value(struct hash_table *variable_context)
{