summaryrefslogtreecommitdiffstats
path: root/src/glsl/ir_constant_expression.cpp
diff options
context:
space:
mode:
authorOlivier Galibert <[email protected]>2012-05-02 23:11:39 +0200
committerKenneth Graunke <[email protected]>2012-05-08 12:55:47 -0700
commita270e86d382597d4d01ebcfa1693e21d778cbe6d (patch)
tree6c6ffca23f454b70e1edda4fe3efe19e83a00fff /src/glsl/ir_constant_expression.cpp
parent6e4852a3a5f3cbe52c53d91d343a37861f207563 (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/ir_constant_expression.cpp')
-rw-r--r--src/glsl/ir_constant_expression.cpp92
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)
{