util/hash_set: Rework the API to know about hashing
[mesa.git] / src / glsl / glsl_types.h
index 69ad4b8655450c9b5d64b65d4b80d35421b57001..474b1291424ed5722e702601545c5e499e5e653f 100644 (file)
@@ -53,6 +53,7 @@ enum glsl_base_type {
    GLSL_TYPE_FLOAT,
    GLSL_TYPE_BOOL,
    GLSL_TYPE_SAMPLER,
+   GLSL_TYPE_IMAGE,
    GLSL_TYPE_ATOMIC_UINT,
    GLSL_TYPE_STRUCT,
    GLSL_TYPE_INTERFACE,
@@ -78,9 +79,30 @@ enum glsl_interface_packing {
    GLSL_INTERFACE_PACKING_PACKED
 };
 
+enum glsl_matrix_layout {
+   /**
+    * The layout of the matrix is inherited from the object containing the
+    * matrix (the top level structure or the uniform block).
+    */
+   GLSL_MATRIX_LAYOUT_INHERITED,
+
+   /**
+    * Explicit column-major layout
+    *
+    * If a uniform block doesn't have an explicit layout set, it will default
+    * to this layout.
+    */
+   GLSL_MATRIX_LAYOUT_COLUMN_MAJOR,
+
+   /**
+    * Row-major layout
+    */
+   GLSL_MATRIX_LAYOUT_ROW_MAJOR
+};
+
 #ifdef __cplusplus
 #include "GL/gl.h"
-#include "ralloc.h"
+#include "util/ralloc.h"
 
 struct glsl_type {
    GLenum gl_type;
@@ -89,8 +111,9 @@ struct glsl_type {
    unsigned sampler_dimensionality:3; /**< \see glsl_sampler_dim */
    unsigned sampler_shadow:1;
    unsigned sampler_array:1;
-   unsigned sampler_type:2;    /**< Type of data returned using this sampler.
-                               * only \c GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
+   unsigned sampler_type:2;    /**< Type of data returned using this
+                               * sampler or image.  Only \c
+                               * GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
                                * and \c GLSL_TYPE_UINT are valid.
                                */
    unsigned interface_packing:2;
@@ -99,16 +122,18 @@ struct glsl_type {
     * easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
    static void* operator new(size_t size)
    {
-      if (glsl_type::mem_ctx == NULL) {
-        glsl_type::mem_ctx = ralloc_context(NULL);
-        assert(glsl_type::mem_ctx != NULL);
-      }
+      mtx_lock(&glsl_type::mutex);
+
+      /* mem_ctx should have been created by the static members */
+      assert(glsl_type::mem_ctx != NULL);
 
       void *type;
 
       type = ralloc_size(glsl_type::mem_ctx, size);
       assert(type != NULL);
 
+      mtx_unlock(&glsl_type::mutex);
+
       return type;
    }
 
@@ -116,7 +141,9 @@ struct glsl_type {
     * ralloc_free in that case. */
    static void operator delete(void *type)
    {
+      mtx_lock(&glsl_type::mutex);
       ralloc_free(type);
+      mtx_unlock(&glsl_type::mutex);
    }
 
    /**
@@ -126,17 +153,10 @@ struct glsl_type {
     * these will be 0.
     */
    /*@{*/
-   unsigned vector_elements:3; /**< 1, 2, 3, or 4 vector elements. */
-   unsigned matrix_columns:3;  /**< 1, 2, 3, or 4 matrix columns. */
+   uint8_t vector_elements;    /**< 1, 2, 3, or 4 vector elements. */
+   uint8_t matrix_columns;     /**< 1, 2, 3, or 4 matrix columns. */
    /*@}*/
 
-   /**
-    * Name of the data type
-    *
-    * Will never be \c NULL.
-    */
-   const char *name;
-
    /**
     * For \c GLSL_TYPE_ARRAY, this is the length of the array.  For
     * \c GLSL_TYPE_STRUCT or \c GLSL_TYPE_INTERFACE, it is the number of
@@ -145,6 +165,13 @@ struct glsl_type {
     */
    unsigned length;
 
+   /**
+    * Name of the data type
+    *
+    * Will never be \c NULL.
+    */
+   const char *name;
+
    /**
     * Subtype of composite data types.
     */
@@ -178,7 +205,7 @@ struct glsl_type {
    /**@}*/
 
    /**
-    * For numeric and boolean derrived types returns the basic scalar type
+    * For numeric and boolean derived types returns the basic scalar type
     *
     * If the type is a numeric or boolean scalar, vector, or matrix type,
     * this function gets the scalar type of the individual components.  For
@@ -253,6 +280,15 @@ struct glsl_type {
     */
    unsigned component_slots() const;
 
+   /**
+    * Calculate the number of unique values from glGetUniformLocation for the
+    * elements of the type.
+    *
+    * This is used to allocate slots in the UniformRemapTable, the amount of
+    * locations may not match with actual used storage space by the driver.
+    */
+   unsigned uniform_locations() const;
+
    /**
     * Calculate the number of attribute slots required to hold this type
     *
@@ -312,7 +348,8 @@ struct glsl_type {
     *     integers.
     * \endverbatim
     */
-   bool can_implicitly_convert_to(const glsl_type *desired) const;
+   bool can_implicitly_convert_to(const glsl_type *desired,
+                                  _mesa_glsl_parse_state *state) const;
 
    /**
     * Query whether or not a type is a scalar (non-vector and non-matrix).
@@ -401,6 +438,20 @@ struct glsl_type {
     */
    gl_texture_index sampler_index() const;
 
+   /**
+    * Query whether or not type is an image, or for struct and array
+    * types, contains an image.
+    */
+   bool contains_image() const;
+
+   /**
+    * Query whether or not a type is an image
+    */
+   bool is_image() const
+   {
+      return base_type == GLSL_TYPE_IMAGE;
+   }
+
    /**
     * Query whether or not a type is an array
     */
@@ -441,6 +492,26 @@ struct glsl_type {
       return base_type == GLSL_TYPE_ERROR;
    }
 
+   /**
+    * Query if a type is unnamed/anonymous (named by the parser)
+    */
+   bool is_anonymous() const
+   {
+      return !strncmp(name, "#anon", 5);
+   }
+
+   /**
+    * Get the type stripped of any arrays
+    *
+    * \return
+    * Pointer to the type of elements of the first non-array type for array
+    * types, or pointer to itself for non-array types.
+    */
+   const glsl_type *without_array() const
+   {
+      return this->is_array() ? this->fields.array : this;
+   }
+
    /**
     * Return the amount of atomic counter storage required for a type.
     */
@@ -459,9 +530,14 @@ struct glsl_type {
     */
    bool contains_atomic() const
    {
-      return atomic_size();
+      return atomic_size() > 0;
    }
 
+   /**
+    * Return whether a type contains any opaque types.
+    */
+   bool contains_opaque() const;
+
    /**
     * Query the full type of a matrix row
     *
@@ -526,7 +602,8 @@ struct glsl_type {
    }
 
    /**
-    * Return the number of coordinate components needed for this sampler type.
+    * Return the number of coordinate components needed for this
+    * sampler or image type.
     *
     * This is based purely on the sampler's dimensionality.  For example, this
     * returns 1 for sampler1D, and 3 for sampler2DArray.
@@ -535,9 +612,19 @@ struct glsl_type {
     * a texturing built-in function, since those pack additional values (such
     * as the shadow comparitor or projector) into the coordinate type.
     */
-   int sampler_coordinate_components() const;
+   int coordinate_components() const;
+
+   /**
+    * Compare a record type against another record type.
+    *
+    * This is useful for matching record types declared across shader stages.
+    */
+   bool record_compare(const glsl_type *b) const;
 
 private:
+
+   static mtx_t mutex;
+
    /**
     * ralloc context for all glsl_type allocations
     *
@@ -552,8 +639,8 @@ private:
             glsl_base_type base_type, unsigned vector_elements,
             unsigned matrix_columns, const char *name);
 
-   /** Constructor for sampler types */
-   glsl_type(GLenum gl_type,
+   /** Constructor for sampler or image types */
+   glsl_type(GLenum gl_type, glsl_base_type base_type,
             enum glsl_sampler_dim dim, bool shadow, bool array,
             unsigned type, const char *name);
 
@@ -607,7 +694,6 @@ private:
 struct glsl_struct_field {
    const struct glsl_type *type;
    const char *name;
-   bool row_major;
 
    /**
     * For interface blocks, gl_varying_slot corresponding to the input/output
@@ -629,6 +715,23 @@ struct glsl_struct_field {
     * in ir_variable::centroid).  0 otherwise.
     */
    unsigned centroid:1;
+
+   /**
+    * For interface blocks, 1 if this variable uses sample interpolation (as
+    * in ir_variable::sample). 0 otherwise.
+    */
+   unsigned sample:1;
+
+   /**
+    * Layout of the matrix.  Uses glsl_matrix_layout values.
+    */
+   unsigned matrix_layout:2;
+
+   /**
+    * For interface blocks, it has a value if this variable uses multiple vertex
+    * streams (as in ir_variable::stream). -1 otherwise.
+    */
+   int stream;
 };
 
 static inline unsigned int