[Mesa-dev] [PATCH 3/5] Add a constant_referenced method to ir_dereference*

Olivier Galibert galibert at pobox.com
Fri Apr 27 01:28:02 PDT 2012


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 at 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



More information about the mesa-dev mailing list