diff options
author | Olivier Galibert <[email protected]> | 2012-05-02 23:11:39 +0200 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2012-05-08 12:55:47 -0700 |
commit | a270e86d382597d4d01ebcfa1693e21d778cbe6d (patch) | |
tree | 6c6ffca23f454b70e1edda4fe3efe19e83a00fff /src/glsl | |
parent | 6e4852a3a5f3cbe52c53d91d343a37861f207563 (diff) |
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 <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Reviewed-by: Eric Anholt <[email protected]> [v1]
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ir.h | 36 | ||||
-rw-r--r-- | src/glsl/ir_constant_expression.cpp | 92 |
2 files changed, 128 insertions, 0 deletions
diff --git a/src/glsl/ir.h b/src/glsl/ir.h index d7df41d893c..dc96e1fe9ed 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -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); 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) { |