* 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;
};
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
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);
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);
}
+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)
{
}
+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)
{
}
+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)
{