Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / glsl / glsl_types.h
index 0b63d4850e1e8a04e1106e119a6f9d747769b488..28e2e93a30565f07f96fa793b61e8ea8d702e5bb 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <string.h>
 #include <assert.h>
-#include "main/mtypes.h" /* for gl_texture_index, C++'s enum rules are broken */
 
 #ifdef __cplusplus
 extern "C" {
@@ -51,14 +50,17 @@ enum glsl_base_type {
    GLSL_TYPE_UINT = 0,
    GLSL_TYPE_INT,
    GLSL_TYPE_FLOAT,
+   GLSL_TYPE_DOUBLE,
    GLSL_TYPE_BOOL,
    GLSL_TYPE_SAMPLER,
    GLSL_TYPE_IMAGE,
    GLSL_TYPE_ATOMIC_UINT,
    GLSL_TYPE_STRUCT,
+   GLSL_TYPE_FUNCTION,
    GLSL_TYPE_INTERFACE,
    GLSL_TYPE_ARRAY,
    GLSL_TYPE_VOID,
+   GLSL_TYPE_SUBROUTINE,
    GLSL_TYPE_ERROR
 };
 
@@ -79,9 +81,31 @@ 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"
+#include "main/mtypes.h" /* for gl_texture_index, C++'s enum rules are broken */
 
 struct glsl_type {
    GLenum gl_type;
@@ -101,16 +125,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;
    }
 
@@ -118,7 +144,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);
    }
 
    /**
@@ -128,17 +156,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
@@ -147,12 +168,19 @@ struct glsl_type {
     */
    unsigned length;
 
+   /**
+    * Name of the data type
+    *
+    * Will never be \c NULL.
+    */
+   const char *name;
+
    /**
     * Subtype of composite data types.
     */
    union {
       const struct glsl_type *array;            /**< Type of array elements. */
-      const struct glsl_type *parameters;       /**< Parameters to function. */
+      struct glsl_function_param *parameters;   /**< Parameters to function. */
       struct glsl_struct_field *structure;      /**< List of struct fields. */
    } fields;
 
@@ -174,6 +202,7 @@ struct glsl_type {
     * @{
     */
    static const glsl_type *vec(unsigned components);
+   static const glsl_type *dvec(unsigned components);
    static const glsl_type *ivec(unsigned components);
    static const glsl_type *uvec(unsigned components);
    static const glsl_type *bvec(unsigned components);
@@ -200,24 +229,21 @@ struct glsl_type {
     */
    const glsl_type *get_scalar_type() const;
 
-   /**
-    * Query the type of elements in an array
-    *
-    * \return
-    * Pointer to the type of elements in the array for array types, or \c NULL
-    * for non-array types.
-    */
-   const glsl_type *element_type() const
-   {
-      return is_array() ? fields.array : NULL;
-   }
-
    /**
     * Get the instance of a built-in scalar, vector, or matrix type
     */
    static const glsl_type *get_instance(unsigned base_type, unsigned rows,
                                        unsigned columns);
 
+   /**
+    * Get the instance of a sampler type
+    */
+   static const glsl_type *get_sampler_instance(enum glsl_sampler_dim dim,
+                                                bool shadow,
+                                                bool array,
+                                                glsl_base_type type);
+
+
    /**
     * Get the instance of an array type
     */
@@ -239,6 +265,23 @@ struct glsl_type {
                                                  enum glsl_interface_packing packing,
                                                  const char *block_name);
 
+   /**
+    * Get the instance of a function type
+    */
+   static const glsl_type *get_function_instance(const struct glsl_type *return_type,
+                                                 const glsl_function_param *parameters,
+                                                 unsigned num_params);
+   /**
+    * Get the instance of an subroutine type
+    */
+   static const glsl_type *get_subroutine_instance(const char *subroutine_name);
+
+   /**
+    * Get the type resulting from a multiplication of \p type_a * \p type_b
+    */
+   static const glsl_type *get_mul_type(const glsl_type *type_a,
+                                        const glsl_type *type_b);
+
    /**
     * Query the total number of scalars that make up a scalar, vector or matrix
     */
@@ -258,6 +301,9 @@ struct glsl_type {
    /**
     * 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;
 
@@ -350,7 +396,7 @@ struct glsl_type {
    bool is_matrix() const
    {
       /* GLSL only has float matrices. */
-      return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT);
+      return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT || base_type == GLSL_TYPE_DOUBLE);
    }
 
    /**
@@ -358,7 +404,7 @@ struct glsl_type {
     */
    bool is_numeric() const
    {
-      return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_FLOAT);
+      return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_DOUBLE);
    }
 
    /**
@@ -375,6 +421,12 @@ struct glsl_type {
     */
    bool contains_integer() const;
 
+   /**
+    * Query whether or not type is a double type, or for struct and array
+    * types, contains a double type.
+    */
+   bool contains_double() const;
+
    /**
     * Query whether or not a type is a float type
     */
@@ -383,6 +435,14 @@ struct glsl_type {
       return base_type == GLSL_TYPE_FLOAT;
    }
 
+   /**
+    * Query whether or not a type is a double type
+    */
+   bool is_double() const
+   {
+      return base_type == GLSL_TYPE_DOUBLE;
+   }
+
    /**
     * Query whether or not a type is a non-array boolean type
     */
@@ -464,6 +524,38 @@ struct glsl_type {
       return base_type == GLSL_TYPE_ERROR;
    }
 
+   /**
+    * Query if a type is unnamed/anonymous (named by the parser)
+    */
+
+   bool is_subroutine() const
+   {
+      return base_type == GLSL_TYPE_SUBROUTINE;
+   }
+   bool contains_subroutine() const;
+
+   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
+   {
+      const glsl_type *t = this;
+
+      while (t->is_array())
+         t = t->fields.array;
+
+      return t;
+   }
+
    /**
     * Return the amount of atomic counter storage required for a type.
     */
@@ -472,7 +564,7 @@ struct glsl_type {
       if (base_type == GLSL_TYPE_ATOMIC_UINT)
          return ATOMIC_COUNTER_SIZE;
       else if (is_array())
-         return length * element_type()->atomic_size();
+         return length * fields.array->atomic_size();
       else
          return 0;
    }
@@ -574,6 +666,9 @@ struct glsl_type {
    bool record_compare(const glsl_type *b) const;
 
 private:
+
+   static mtx_t mutex;
+
    /**
     * ralloc context for all glsl_type allocations
     *
@@ -601,9 +696,16 @@ private:
    glsl_type(const glsl_struct_field *fields, unsigned num_fields,
             enum glsl_interface_packing packing, const char *name);
 
+   /** Constructor for interface types */
+   glsl_type(const glsl_type *return_type,
+             const glsl_function_param *params, unsigned num_params);
+
    /** Constructor for array types */
    glsl_type(const glsl_type *array, unsigned length);
 
+   /** Constructor for subroutine types */
+   glsl_type(const char *name);
+
    /** Hash table containing the known array types. */
    static struct hash_table *array_types;
 
@@ -613,7 +715,13 @@ private:
    /** Hash table containing the known interface types. */
    static struct hash_table *interface_types;
 
-   static int record_key_compare(const void *a, const void *b);
+   /** Hash table containing the known function types. */
+   static struct hash_table *function_types;
+
+   /** Hash table containing the known subroutine types. */
+   static struct hash_table *subroutine_types;
+
+   static bool record_key_compare(const void *a, const void *b);
    static unsigned record_key_hash(const void *key);
 
    /**
@@ -640,10 +748,13 @@ private:
    /*@}*/
 };
 
+#undef DECL_TYPE
+#undef STRUCT_TYPE
+#endif /* __cplusplus */
+
 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
@@ -672,11 +783,44 @@ struct glsl_struct_field {
     */
    unsigned sample:1;
 
+   /**
+    * Layout of the matrix.  Uses glsl_matrix_layout values.
+    */
+   unsigned matrix_layout:2;
+
+   /**
+    * For interface blocks, 1 if this variable is a per-patch input or output
+    * (as in ir_variable::patch). 0 otherwise.
+    */
+   unsigned patch:1;
+
    /**
     * For interface blocks, it has a value if this variable uses multiple vertex
     * streams (as in ir_variable::stream). -1 otherwise.
     */
    int stream;
+
+#ifdef __cplusplus
+   glsl_struct_field(const struct glsl_type *_type, const char *_name)
+      : type(_type), name(_name), location(-1), interpolation(0), centroid(0),
+        sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0),
+        stream(-1)
+   {
+      /* empty */
+   }
+
+   glsl_struct_field()
+   {
+      /* empty */
+   }
+#endif
+};
+
+struct glsl_function_param {
+   const struct glsl_type *type;
+
+   bool in;
+   bool out;
 };
 
 static inline unsigned int
@@ -685,8 +829,4 @@ glsl_align(unsigned int a, unsigned int align)
    return (a + align - 1) / align * align;
 }
 
-#undef DECL_TYPE
-#undef STRUCT_TYPE
-#endif /* __cplusplus */
-
 #endif /* GLSL_TYPES_H */