diff options
Diffstat (limited to 'src/glsl/ir_constant_expression.cpp')
-rw-r--r-- | src/glsl/ir_constant_expression.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index bf4bb319e8b..418019abb63 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -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) { |