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 <galib...@pobox.com> --- src/glsl/ir.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/glsl/ir.h | 36 ++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index fbbde20..cfa806d 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -25,6 +25,7 @@ #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" +#include "program/hash_table.h" ir_rvalue::ir_rvalue() { @@ -1048,6 +1049,18 @@ ir_dereference_variable::ir_dereference_variable(ir_variable *var) this->type = var->type; } +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->name); + offset = 0; + } else { + store = NULL; + offset = 0; + } +} ir_dereference_array::ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index) @@ -1087,6 +1100,59 @@ ir_dereference_array::set_array(ir_rvalue *value) } } +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_dereference_record::ir_dereference_record(ir_rvalue *value, const char *field) @@ -1111,6 +1177,31 @@ ir_dereference_record::ir_dereference_record(ir_variable *var, this->type = this->record->type->field_type(field); } +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; +} + bool ir_dereference::is_lvalue() const { diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 6e67085..c211880 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1450,6 +1450,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; }; @@ -1475,6 +1484,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 @@ -1524,6 +1542,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); @@ -1558,6 +1585,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); -- 1.7.10.280.gaa39 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev