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:

committed by
Kenneth Graunke

parent
6e4852a3a5
commit
a270e86d38
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user