virtual class ir_return * as_return() { return NULL; }
virtual class ir_if * as_if() { return NULL; }
virtual class ir_swizzle * as_swizzle() { return NULL; }
+ virtual class ir_texture * as_texture() { return NULL; }
virtual class ir_constant * as_constant() { return NULL; }
virtual class ir_discard * as_discard() { return NULL; }
virtual class ir_jump * as_jump() { return NULL; }
/*@}*/
+ /**
+ * IR equality method: Return true if the referenced instruction would
+ * return the same value as this one.
+ *
+ * This intended to be used for CSE and algebraic optimizations, on rvalues
+ * in particular. No support for other instruction types (assignments,
+ * jumps, calls, etc.) is planned.
+ */
+ virtual bool equals(ir_instruction *ir);
+
protected:
ir_instruction()
{
ir_var_mode_count /**< Number of variable modes */
};
+/**
+ * Enum keeping track of how a variable was declared. For error checking of
+ * the gl_PerVertex redeclaration rules.
+ */
+enum ir_var_declaration_type {
+ /**
+ * Normal declaration (for most variables, this means an explicit
+ * declaration. Exception: temporaries are always implicitly declared, but
+ * they still use ir_var_declared_normally).
+ *
+ * Note: an ir_variable that represents a named interface block uses
+ * ir_var_declared_normally.
+ */
+ ir_var_declared_normally = 0,
+
+ /**
+ * Variable was explicitly declared (or re-declared) in an unnamed
+ * interface block.
+ */
+ ir_var_declared_in_block,
+
+ /**
+ * Variable is an implicitly declared built-in that has not been explicitly
+ * re-declared by the shader.
+ */
+ ir_var_declared_implicitly,
+};
+
/**
* \brief Layout qualifiers for gl_FragDepth.
*
int swizzle;
};
+
+/**
+ * Get the string value for an interpolation qualifier
+ *
+ * \return The string that would be used in a shader to specify \c
+ * mode will be returned.
+ *
+ * This function is used to generate error messages of the form "shader
+ * uses %s interpolation qualifier", so in the case where there is no
+ * interpolation qualifier, it returns "no".
+ *
+ * This function should only be used on a shader input or output variable.
+ */
+const char *interpolation_string(unsigned interpolation);
+
+
class ir_variable : public ir_instruction {
public:
ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
- /**
- * Get the string value for the interpolation qualifier
- *
- * \return The string that would be used in a shader to specify \c
- * mode will be returned.
- *
- * This function is used to generate error messages of the form "shader
- * uses %s interpolation qualifier", so in the case where there is no
- * interpolation qualifier, it returns "no".
- *
- * This function should only be used on a shader input or output variable.
- */
- const char *interpolation_string() const;
-
/**
* Determine how this variable should be interpolated based on its
* interpolation qualifier (if present), whether it is gl_Color or
|| (t->is_array() && t->fields.array == this->interface_type);
}
+ /**
+ * Set this->interface_type on a newly created variable.
+ */
+ void init_interface_type(const struct glsl_type *type)
+ {
+ assert(this->interface_type == NULL);
+ this->interface_type = type;
+ if (this->is_interface_instance()) {
+ this->max_ifc_array_access =
+ rzalloc_array(this, unsigned, type->length);
+ }
+ }
+
+ /**
+ * Change this->interface_type on a variable that previously had a
+ * different, but compatible, interface_type. This is used during linking
+ * to set the size of arrays in interface blocks.
+ */
+ void change_interface_type(const struct glsl_type *type)
+ {
+ if (this->max_ifc_array_access != NULL) {
+ /* max_ifc_array_access has already been allocated, so make sure the
+ * new interface has the same number of fields as the old one.
+ */
+ assert(this->interface_type->length == type->length);
+ }
+ this->interface_type = type;
+ }
+
+ /**
+ * Change this->interface_type on a variable that previously had a
+ * different, and incompatible, interface_type. This is used during
+ * compilation to handle redeclaration of the built-in gl_PerVertex
+ * interface block.
+ */
+ void reinit_interface_type(const struct glsl_type *type)
+ {
+ if (this->max_ifc_array_access != NULL) {
+#ifndef _NDEBUG
+ /* Redeclaring gl_PerVertex is only allowed if none of the built-ins
+ * it defines have been accessed yet; so it's safe to throw away the
+ * old max_ifc_array_access pointer, since all of its values are
+ * zero.
+ */
+ for (unsigned i = 0; i < this->interface_type->length; i++)
+ assert(this->max_ifc_array_access[i] == 0);
+#endif
+ ralloc_free(this->max_ifc_array_access);
+ this->max_ifc_array_access = NULL;
+ }
+ this->interface_type = NULL;
+ init_interface_type(type);
+ }
+
+ const glsl_type *get_interface_type() const
+ {
+ return this->interface_type;
+ }
+
/**
* Declared type of the variable
*/
*/
unsigned max_array_access;
+ /**
+ * For variables which satisfy the is_interface_instance() predicate, this
+ * points to an array of integers such that if the ith member of the
+ * interface block is an array, max_ifc_array_access[i] is the maximum
+ * array element of that member that has been accessed. If the ith member
+ * of the interface block is not an array, max_ifc_array_access[i] is
+ * unused.
+ *
+ * For variables whose type is not an interface block, this pointer is
+ * NULL.
+ */
+ unsigned *max_ifc_array_access;
+
/**
* Is the variable read-only?
*
*/
unsigned assigned:1;
+ /**
+ * Enum indicating how the variable was declared. See
+ * ir_var_declaration_type.
+ *
+ * This is used to detect certain kinds of illegal variable redeclarations.
+ */
+ unsigned how_declared:2;
+
/**
* Storage class of the variable.
*
*/
unsigned location_frac:2;
+ /**
+ * Non-zero if this variable was created by lowering a named interface
+ * block which was not an array.
+ *
+ * Note that this variable and \c from_named_ifc_block_array will never
+ * both be non-zero.
+ */
+ unsigned from_named_ifc_block_nonarray:1;
+
+ /**
+ * Non-zero if this variable was created by lowering a named interface
+ * block which was an array.
+ *
+ * Note that this variable and \c from_named_ifc_block_nonarray will never
+ * both be non-zero.
+ */
+ unsigned from_named_ifc_block_array:1;
+
/**
* \brief Layout qualifier for gl_FragDepth.
*
*/
int binding;
+ /**
+ * Location an atomic counter is stored at.
+ */
+ struct {
+ unsigned buffer_index;
+ unsigned offset;
+ } atomic;
+
/**
* Built-in state that backs this uniform
*
*/
ir_constant *constant_initializer;
+private:
/**
* For variables that are in an interface block or are an instance of an
* interface block, this is the \c GLSL_TYPE_INTERFACE type for that block.
/** Whether or not this function signature is a built-in. */
bool is_builtin() const;
+ /**
+ * Whether or not this function is an intrinsic to be implemented
+ * by the driver.
+ */
+ bool is_intrinsic;
+
/** Whether or not a built-in is available for this shader. */
bool is_builtin_available(const _mesa_glsl_parse_state *state) const;
* If \c from and \c to are the same value, the loop will execute once.
*/
/*@{*/
- ir_rvalue *from; /** Value of the loop counter on the first
- * iteration of the loop.
- */
- ir_rvalue *to; /** Value of the loop counter on the last
- * iteration of the loop.
- */
+
+ /**
+ * Value which should be assigned to \c counter before the first iteration
+ * of the loop. Must be non-null whenever \c counter is non-null, and vice
+ * versa.
+ */
+ ir_rvalue *from;
+
+ /**
+ * Value which \c counter should be compared to in order to determine
+ * whether to exit the loop. Must be non-null whenever \c counter is
+ * non-null, and vice versa.
+ */
+ ir_rvalue *to;
+
+ /**
+ * Value which should be added to \c counter at the end of each loop
+ * iteration. Must be non-null whenever \c counter is non-null, and vice
+ * versa.
+ */
ir_rvalue *increment;
+
+ /**
+ * Variable which counts loop iterations. This is a brand new ir_variable
+ * declaration (not a reference to a previously declared ir_variable, as in
+ * ir_dereference_variable).
+ */
ir_variable *counter;
/**
* If any of the loop control fields are non-\c NULL, this field must be
* one of \c ir_binop_less, \c ir_binop_greater, \c ir_binop_lequal,
* \c ir_binop_gequal, \c ir_binop_equal, or \c ir_binop_nequal.
+ *
+ * Ignored if \c counter is NULL.
*/
int cmp;
/*@}*/
ir_binop_add,
ir_binop_sub,
- ir_binop_mul,
+ ir_binop_mul, /**< Floating-point or low 32-bit integer multiply. */
+ ir_binop_imul_high, /**< Calculates the high 32-bits of a 64-bit multiply. */
ir_binop_div,
/**
return this;
}
+ virtual bool equals(ir_instruction *ir);
+
virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
/**
v->visit(this);
}
+ virtual ir_texture *as_texture()
+ {
+ return this;
+ }
+
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+ virtual bool equals(ir_instruction *ir);
+
/**
* Return a string representing the ir_texture_opcode.
*/
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+ virtual bool equals(ir_instruction *ir);
+
bool is_lvalue() const
{
return val->is_lvalue() && !mask.has_duplicates;
return this;
}
+ virtual bool equals(ir_instruction *ir);
+
/**
* Get the variable that is ultimately referenced by an r-value
*/
return this;
}
+ virtual bool equals(ir_instruction *ir);
+
/**
* Get the variable that is ultimately referenced by an r-value
*/
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+ virtual bool equals(ir_instruction *ir);
+
/**
* Get a particular component of a constant as a specific type
*
prototype_string(const glsl_type *return_type, const char *name,
exec_list *parameters);
+const char *
+mode_string(const ir_variable *var);
+
extern "C" {
#endif /* __cplusplus */