Added few more stubs so that control reaches to DestroyDevice().
[mesa.git] / src / compiler / glsl_types.h
index 00133d9cb258b16a557aae0f1bd6609579b06d8a..8058425e0d087a195339510caacd6f03a9c2d757 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
-#pragma once
 #ifndef GLSL_TYPES_H
 #define GLSL_TYPES_H
 
 #include <string.h>
 #include <assert.h>
+#include <stdio.h>
+
+#include "shader_enums.h"
+#include "c11/threads.h"
+#include "util/blob.h"
+#include "util/format/u_format.h"
+#include "util/macros.h"
+
+#ifdef __cplusplus
+#include "main/config.h"
+#endif
+
+struct glsl_type;
 
 #ifdef __cplusplus
 extern "C" {
@@ -37,20 +49,39 @@ struct _mesa_glsl_parse_state;
 struct glsl_symbol_table;
 
 extern void
-_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
+glsl_type_singleton_init_or_ref();
 
 extern void
-_mesa_glsl_release_types(void);
+glsl_type_singleton_decref();
 
-#ifdef __cplusplus
-}
-#endif
+extern void
+_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
+
+void
+glsl_print_type(FILE *f, const struct glsl_type *t);
+
+void encode_type_to_blob(struct blob *blob, const struct glsl_type *type);
+
+const struct glsl_type *decode_type_from_blob(struct blob_reader *blob);
+
+typedef void (*glsl_type_size_align_func)(const struct glsl_type *type,
+                                          unsigned *size, unsigned *align);
 
 enum glsl_base_type {
+   /* Note: GLSL_TYPE_UINT, GLSL_TYPE_INT, and GLSL_TYPE_FLOAT must be 0, 1,
+    * and 2 so that they will fit in the 2 bits of glsl_type::sampled_type.
+    */
    GLSL_TYPE_UINT = 0,
    GLSL_TYPE_INT,
    GLSL_TYPE_FLOAT,
+   GLSL_TYPE_FLOAT16,
    GLSL_TYPE_DOUBLE,
+   GLSL_TYPE_UINT8,
+   GLSL_TYPE_INT8,
+   GLSL_TYPE_UINT16,
+   GLSL_TYPE_INT16,
+   GLSL_TYPE_UINT64,
+   GLSL_TYPE_INT64,
    GLSL_TYPE_BOOL,
    GLSL_TYPE_SAMPLER,
    GLSL_TYPE_IMAGE,
@@ -60,9 +91,133 @@ enum glsl_base_type {
    GLSL_TYPE_ARRAY,
    GLSL_TYPE_VOID,
    GLSL_TYPE_SUBROUTINE,
+   GLSL_TYPE_FUNCTION,
    GLSL_TYPE_ERROR
 };
 
+/* Return the bit size of a type. Note that this differs from 
+ * glsl_get_bit_size in that it returns 32 bits for bools, whereas at
+ * the NIR level we would want to return 1 bit for bools.
+ */
+static unsigned glsl_base_type_bit_size(enum glsl_base_type type)
+{
+   switch (type) {
+   case GLSL_TYPE_BOOL:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_FLOAT: /* TODO handle mediump */
+   case GLSL_TYPE_SUBROUTINE:
+      return 32;
+
+   case GLSL_TYPE_FLOAT16:
+   case GLSL_TYPE_UINT16:
+   case GLSL_TYPE_INT16:
+      return 16;
+
+   case GLSL_TYPE_UINT8:
+   case GLSL_TYPE_INT8:
+      return 8;
+
+   case GLSL_TYPE_DOUBLE:
+   case GLSL_TYPE_INT64:
+   case GLSL_TYPE_UINT64:
+   case GLSL_TYPE_IMAGE:
+   case GLSL_TYPE_SAMPLER:
+      return 64;
+
+   default:
+      /* For GLSL_TYPE_STRUCT etc, it should be ok to return 0. This usually
+       * happens when calling this method through is_64bit and is_16bit
+       * methods
+       */
+      return 0;
+   }
+
+   return 0;
+}
+
+static inline bool glsl_base_type_is_16bit(enum glsl_base_type type)
+{
+   return glsl_base_type_bit_size(type) == 16;
+}
+
+static inline bool glsl_base_type_is_64bit(enum glsl_base_type type)
+{
+   return glsl_base_type_bit_size(type) == 64;
+}
+
+static inline bool glsl_base_type_is_integer(enum glsl_base_type type)
+{
+   return type == GLSL_TYPE_UINT8 ||
+          type == GLSL_TYPE_INT8 ||
+          type == GLSL_TYPE_UINT16 ||
+          type == GLSL_TYPE_INT16 ||
+          type == GLSL_TYPE_UINT ||
+          type == GLSL_TYPE_INT ||
+          type == GLSL_TYPE_UINT64 ||
+          type == GLSL_TYPE_INT64 ||
+          type == GLSL_TYPE_BOOL ||
+          type == GLSL_TYPE_SAMPLER ||
+          type == GLSL_TYPE_IMAGE;
+}
+
+static inline unsigned int
+glsl_base_type_get_bit_size(const enum glsl_base_type base_type)
+{
+   switch (base_type) {
+   case GLSL_TYPE_BOOL:
+      return 1;
+
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_FLOAT: /* TODO handle mediump */
+   case GLSL_TYPE_SUBROUTINE:
+      return 32;
+
+   case GLSL_TYPE_FLOAT16:
+   case GLSL_TYPE_UINT16:
+   case GLSL_TYPE_INT16:
+      return 16;
+
+   case GLSL_TYPE_UINT8:
+   case GLSL_TYPE_INT8:
+      return 8;
+
+   case GLSL_TYPE_DOUBLE:
+   case GLSL_TYPE_INT64:
+   case GLSL_TYPE_UINT64:
+   case GLSL_TYPE_IMAGE:
+   case GLSL_TYPE_SAMPLER:
+      return 64;
+
+   default:
+      unreachable("unknown base type");
+   }
+
+   return 0;
+}
+
+static inline enum glsl_base_type
+glsl_unsigned_base_type_of(enum glsl_base_type type)
+{
+   switch (type) {
+   case GLSL_TYPE_INT:
+      return GLSL_TYPE_UINT;
+   case GLSL_TYPE_INT8:
+      return GLSL_TYPE_UINT8;
+   case GLSL_TYPE_INT16:
+      return GLSL_TYPE_UINT16;
+   case GLSL_TYPE_INT64:
+      return GLSL_TYPE_UINT64;
+   default:
+      assert(type == GLSL_TYPE_UINT ||
+             type == GLSL_TYPE_UINT8 ||
+             type == GLSL_TYPE_UINT16 ||
+             type == GLSL_TYPE_UINT64);
+      return type;
+   }
+}
+
 enum glsl_sampler_dim {
    GLSL_SAMPLER_DIM_1D = 0,
    GLSL_SAMPLER_DIM_2D,
@@ -71,15 +226,13 @@ enum glsl_sampler_dim {
    GLSL_SAMPLER_DIM_RECT,
    GLSL_SAMPLER_DIM_BUF,
    GLSL_SAMPLER_DIM_EXTERNAL,
-   GLSL_SAMPLER_DIM_MS
+   GLSL_SAMPLER_DIM_MS,
+   GLSL_SAMPLER_DIM_SUBPASS, /* for vulkan input attachments */
+   GLSL_SAMPLER_DIM_SUBPASS_MS, /* for multisampled vulkan input attachments */
 };
 
-enum glsl_interface_packing {
-   GLSL_INTERFACE_PACKING_STD140,
-   GLSL_INTERFACE_PACKING_SHARED,
-   GLSL_INTERFACE_PACKING_PACKED,
-   GLSL_INTERFACE_PACKING_STD430
-};
+int
+glsl_get_sampler_dim_coordinate_components(enum glsl_sampler_dim dim);
 
 enum glsl_matrix_layout {
    /**
@@ -110,52 +263,42 @@ enum {
 };
 
 #ifdef __cplusplus
+} /* extern "C" */
+
 #include "GL/gl.h"
 #include "util/ralloc.h"
-#include "main/mtypes.h" /* for gl_texture_index, C++'s enum rules are broken */
+#include "main/menums.h" /* for gl_texture_index, C++'s enum rules are broken */
 
 struct glsl_type {
    GLenum gl_type;
-   glsl_base_type base_type;
+   glsl_base_type base_type:8;
+
+   glsl_base_type sampled_type:8; /**< 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 sampler_dimensionality:3; /**< \see glsl_sampler_dim */
+   unsigned sampler_dimensionality:4; /**< \see glsl_sampler_dim */
    unsigned sampler_shadow:1;
    unsigned sampler_array:1;
-   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;
+   unsigned interface_row_major:1;
 
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
-   static void* operator new(size_t size)
-   {
-      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;
-   }
+   /**
+    * For \c GLSL_TYPE_STRUCT this specifies if the struct is packed or not.
+    *
+    * Only used for Compute kernels
+    */
+   unsigned packed:1;
 
-   /* If the user *does* call delete, that's OK, we will just
-    * ralloc_free in that case. */
-   static void operator delete(void *type)
+private:
+   glsl_type() : mem_ctx(NULL)
    {
-      mtx_lock(&glsl_type::mutex);
-      ralloc_free(type);
-      mtx_unlock(&glsl_type::mutex);
+      // Dummy constructor, just for the sake of ASSERT_BITFIELD_SIZE.
    }
 
+public:
    /**
     * \name Vector and matrix element counts
     *
@@ -182,12 +325,26 @@ struct glsl_type {
     */
    const char *name;
 
+   /**
+    * Explicit array, matrix, or vector stride.  This is used to communicate
+    * explicit array layouts from SPIR-V.  Should be 0 if the type has no
+    * explicit stride.
+    */
+   unsigned explicit_stride;
+
+   /**
+    * Explicit alignment. This is used to communicate explicit alignment
+    * constraints. Should be 0 if the type has no explicit alignment
+    * constraint.
+    */
+   unsigned explicit_alignment;
+
    /**
     * 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;
 
@@ -208,11 +365,19 @@ struct glsl_type {
     * Convenience accessors for vector types (shorter than get_instance()).
     * @{
     */
+   static const glsl_type *vec(unsigned components, const glsl_type *const ts[]);
    static const glsl_type *vec(unsigned components);
+   static const glsl_type *f16vec(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);
+   static const glsl_type *i64vec(unsigned components);
+   static const glsl_type *u64vec(unsigned components);
+   static const glsl_type *i16vec(unsigned components);
+   static const glsl_type *u16vec(unsigned components);
+   static const glsl_type *i8vec(unsigned components);
+   static const glsl_type *u8vec(unsigned components);
    /**@}*/
 
    /**
@@ -236,11 +401,34 @@ struct glsl_type {
     */
    const glsl_type *get_scalar_type() const;
 
+   /**
+    * Gets the "bare" type without any decorations or layout information.
+    */
+   const glsl_type *get_bare_type() const;
+
+   /**
+    * Gets the float16 version of this type.
+    */
+   const glsl_type *get_float16_type() const;
+
+   /**
+    * Gets the int16 version of this type.
+    */
+   const glsl_type *get_int16_type() const;
+
+   /**
+    * Gets the uint16 version of this type.
+    */
+   const glsl_type *get_uint16_type() const;
+
    /**
     * 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);
+                                        unsigned columns,
+                                        unsigned explicit_stride = 0,
+                                        bool row_major = false,
+                                        unsigned explicit_alignment = 0);
 
    /**
     * Get the instance of a sampler type
@@ -250,19 +438,24 @@ struct glsl_type {
                                                 bool array,
                                                 glsl_base_type type);
 
+   static const glsl_type *get_image_instance(enum glsl_sampler_dim dim,
+                                              bool array, glsl_base_type type);
 
    /**
     * Get the instance of an array type
     */
    static const glsl_type *get_array_instance(const glsl_type *base,
-                                             unsigned elements);
+                                              unsigned elements,
+                                              unsigned explicit_stride = 0);
 
    /**
     * Get the instance of a record type
     */
-   static const glsl_type *get_record_instance(const glsl_struct_field *fields,
+   static const glsl_type *get_struct_instance(const glsl_struct_field *fields,
                                               unsigned num_fields,
-                                              const char *name);
+                                              const char *name,
+                                              bool packed = false,
+                                              unsigned explicit_alignment = 0);
 
    /**
     * Get the instance of an interface block type
@@ -270,6 +463,7 @@ struct glsl_type {
    static const glsl_type *get_interface_instance(const glsl_struct_field *fields,
                                                  unsigned num_fields,
                                                  enum glsl_interface_packing packing,
+                                                 bool row_major,
                                                  const char *block_name);
 
    /**
@@ -277,6 +471,13 @@ struct glsl_type {
     */
    static const glsl_type *get_subroutine_instance(const char *subroutine_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 type resulting from a multiplication of \p type_a * \p type_b
     */
@@ -305,7 +506,7 @@ struct glsl_type {
     * For the initial call, length is the index of the member to find the
     * offset for.
     */
-   unsigned record_location_offset(unsigned length) const;
+   unsigned struct_location_offset(unsigned length) const;
 
    /**
     * Calculate the number of unique values from glGetUniformLocation for the
@@ -316,6 +517,29 @@ struct glsl_type {
     */
    unsigned uniform_locations() const;
 
+   /**
+    * Used to count the number of varyings contained in the type ignoring
+    * innermost array elements.
+    */
+   unsigned varying_count() const;
+
+   /**
+    * Calculate the number of vec4 slots required to hold this type.
+    *
+    * This is the underlying recursive type_size function for
+    * count_attribute_slots() (vertex inputs and varyings) but also for
+    * gallium's !PIPE_CAP_PACKED_UNIFORMS case.
+    */
+   unsigned count_vec4_slots(bool is_gl_vertex_input, bool bindless) const;
+
+   /**
+    * Calculate the number of vec4 slots required to hold this type.
+    *
+    * This is the underlying recursive type_size function for
+    * gallium's PIPE_CAP_PACKED_UNIFORMS case.
+    */
+   unsigned count_dword_slots(bool bindless) const;
+
    /**
     * Calculate the number of attribute slots required to hold this type
     *
@@ -327,8 +551,13 @@ struct glsl_type {
     *
     * For vertex shader attributes - doubles only take one slot.
     * For inter-shader varyings - dvec3/dvec4 take two slots.
+    *
+    * Vulkan doesn’t make this distinction so the argument should always be
+    * false.
     */
-   unsigned count_attribute_slots(bool vertex_input_slots) const;
+   unsigned count_attribute_slots(bool is_gl_vertex_input) const {
+      return count_vec4_slots(is_gl_vertex_input, true);
+   }
 
    /**
     * Alignment in bytes of the start of this type in a std140 uniform
@@ -343,6 +572,11 @@ struct glsl_type {
     */
    unsigned std140_size(bool row_major) const;
 
+   /**
+    * Gets an explicitly laid out type with the std140 layout.
+    */
+   const glsl_type *get_explicit_std140_type(bool row_major) const;
+
    /**
     * Alignment in bytes of the start of this type in a std430 shader
     * storage block.
@@ -362,6 +596,59 @@ struct glsl_type {
     */
    unsigned std430_size(bool row_major) const;
 
+   /**
+    * Gets an explicitly laid out type with the std430 layout.
+    */
+   const glsl_type *get_explicit_std430_type(bool row_major) const;
+
+   /**
+    * Gets an explicitly laid out interface type.
+    */
+   const glsl_type *get_explicit_interface_type(bool supports_std430) const;
+
+   /** Returns an explicitly laid out type given a type and size/align func
+    *
+    * The size/align func is only called for scalar and vector types and the
+    * returned type is otherwise laid out in the natural way as follows:
+    *
+    *  - Arrays and matrices have a stride of ALIGN(elem_size, elem_align).
+    *
+    *  - Structure types have their elements in-order and as tightly packed as
+    *    possible following the alignment required by the size/align func.
+    *
+    *  - All composite types (structures, matrices, and arrays) have an
+    *    alignment equal to the highest alighment of any member of the composite.
+    *
+    * The types returned by this function are likely not suitable for most UBO
+    * or SSBO layout because they do not add the extra array and substructure
+    * alignment that is required by std140 and std430.
+    */
+   const glsl_type *get_explicit_type_for_size_align(glsl_type_size_align_func type_info,
+                                                     unsigned *size, unsigned *align) const;
+
+   /**
+    * Alignment in bytes of the start of this type in OpenCL memory.
+    */
+   unsigned cl_alignment() const;
+
+   /**
+    * Size in bytes of this type in OpenCL memory
+    */
+   unsigned cl_size() const;
+
+   /**
+    * Size in bytes of this type based on its explicit data.
+    *
+    * When using SPIR-V shaders (ARB_gl_spirv), memory layouts are expressed
+    * through explicit offset, stride and matrix layout, so the size
+    * can/should be computed used those values.
+    *
+    * Note that the value returned by this method is only correct if such
+    * values are set, so only with SPIR-V shaders. Should not be used with
+    * GLSL shaders.
+    */
+   unsigned explicit_size(bool align_to_stride=false) const;
+
    /**
     * \brief Can this type be implicitly converted to another?
     *
@@ -406,7 +693,7 @@ struct glsl_type {
    {
       return (vector_elements == 1)
         && (base_type >= GLSL_TYPE_UINT)
-        && (base_type <= GLSL_TYPE_BOOL);
+        && (base_type <= GLSL_TYPE_IMAGE);
    }
 
    /**
@@ -426,7 +713,9 @@ struct glsl_type {
    bool is_matrix() const
    {
       /* GLSL only has float matrices. */
-      return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT || base_type == GLSL_TYPE_DOUBLE);
+      return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT ||
+                                      base_type == GLSL_TYPE_DOUBLE ||
+                                      base_type == GLSL_TYPE_FLOAT16);
    }
 
    /**
@@ -434,17 +723,65 @@ struct glsl_type {
     */
    bool is_numeric() const
    {
-      return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_DOUBLE);
+      return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_INT64);
    }
 
    /**
-    * Query whether or not a type is an integral type
+    * Query whether or not a type is an integer.
     */
    bool is_integer() const
+   {
+      return glsl_base_type_is_integer(base_type);
+   }
+
+   /**
+    * Query whether or not a type is a 16-bit integer.
+    */
+   bool is_integer_16() const
+   {
+      return base_type == GLSL_TYPE_UINT16 || base_type == GLSL_TYPE_INT16;
+   }
+
+   /**
+    * Query whether or not a type is an 32-bit integer.
+    */
+   bool is_integer_32() const
    {
       return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT);
    }
 
+   /**
+    * Query whether or not a type is a 64-bit integer.
+    */
+   bool is_integer_64() const
+   {
+      return base_type == GLSL_TYPE_UINT64 || base_type == GLSL_TYPE_INT64;
+   }
+
+   /**
+    * Query whether or not a type is a 32-bit or 64-bit integer
+    */
+   bool is_integer_32_64() const
+   {
+      return is_integer_32() || is_integer_64();
+   }
+
+   /**
+    * Query whether or not a type is a 16-bit or 32-bit integer
+    */
+   bool is_integer_16_32() const
+   {
+      return is_integer_16() || is_integer_32() || is_integer_64();
+   }
+
+   /**
+    * Query whether or not a type is a 16-bit, 32-bit or 64-bit integer
+    */
+   bool is_integer_16_32_64() const
+   {
+      return is_integer_16() || is_integer_32() || is_integer_64();
+   }
+
    /**
     * Query whether or not type is an integral type, or for struct and array
     * types, contains an integral type.
@@ -452,11 +789,17 @@ 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.
+    * Query whether or not type is a double type, or for struct, interface and
+    * array types, contains a double type.
     */
    bool contains_double() const;
 
+   /**
+    * Query whether or not type is a 64-bit type, or for struct, interface and
+    * array types, contains a double type.
+    */
+   bool contains_64bit() const;
+
    /**
     * Query whether or not a type is a float type
     */
@@ -465,6 +808,56 @@ struct glsl_type {
       return base_type == GLSL_TYPE_FLOAT;
    }
 
+   /**
+    * Query whether or not a type is a half-float or float type
+    */
+   bool is_float_16_32() const
+   {
+      return base_type == GLSL_TYPE_FLOAT16 || is_float();
+   }
+
+   /**
+    * Query whether or not a type is a half-float, float or double
+    */
+   bool is_float_16_32_64() const
+   {
+      return base_type == GLSL_TYPE_FLOAT16 || is_float() || is_double();
+   }
+
+   /**
+    * Query whether or not a type is a float or double
+    */
+   bool is_float_32_64() const
+   {
+      return is_float() || is_double();
+   }
+
+   bool is_int_16_32_64() const
+   {
+      return base_type == GLSL_TYPE_INT16 ||
+             base_type == GLSL_TYPE_INT ||
+             base_type == GLSL_TYPE_INT64;
+   }
+
+   bool is_uint_16_32_64() const
+   {
+      return base_type == GLSL_TYPE_UINT16 ||
+             base_type == GLSL_TYPE_UINT ||
+             base_type == GLSL_TYPE_UINT64;
+   }
+
+   bool is_int_16_32() const
+   {
+      return base_type == GLSL_TYPE_INT ||
+             base_type == GLSL_TYPE_INT16;
+   }
+
+   bool is_uint_16_32() const
+   {
+      return base_type == GLSL_TYPE_UINT ||
+             base_type == GLSL_TYPE_UINT16;
+   }
+
    /**
     * Query whether or not a type is a double type
     */
@@ -474,11 +867,37 @@ struct glsl_type {
    }
 
    /**
-    * Query whether a double takes two slots.
+    * Query whether a 64-bit type takes two slots.
     */
-   bool is_dual_slot_double() const
+   bool is_dual_slot() const
    {
-      return base_type == GLSL_TYPE_DOUBLE && vector_elements > 2;
+      return is_64bit() && vector_elements > 2;
+   }
+
+   /**
+    * Query whether or not a type is 64-bit
+    */
+   bool is_64bit() const
+   {
+      return glsl_base_type_is_64bit(base_type);
+   }
+
+   /**
+    * Query whether or not a type is 16-bit
+    */
+   bool is_16bit() const
+   {
+      return glsl_base_type_is_16bit(base_type);
+   }
+
+   /**
+    * Query whether or not a type is 32-bit
+    */
+   bool is_32bit() const
+   {
+      return base_type == GLSL_TYPE_UINT ||
+             base_type == GLSL_TYPE_INT ||
+             base_type == GLSL_TYPE_FLOAT;
    }
 
    /**
@@ -498,19 +917,25 @@ struct glsl_type {
    }
 
    /**
-    * Query whether or not type is a sampler, or for struct and array
-    * types, contains a sampler.
+    * Query whether or not type is a sampler, or for struct, interface and
+    * array types, contains a sampler.
     */
    bool contains_sampler() const;
 
+   /**
+    * Query whether or not type is an array or for struct, interface and
+    * array types, contains an array.
+    */
+   bool contains_array() const;
+
    /**
     * Get the Mesa texture target index for a sampler type.
     */
    gl_texture_index sampler_index() const;
 
    /**
-    * Query whether or not type is an image, or for struct and array
-    * types, contains an image.
+    * Query whether or not type is an image, or for struct, interface and
+    * array types, contains an image.
     */
    bool contains_image() const;
 
@@ -538,7 +963,7 @@ struct glsl_type {
    /**
     * Query whether or not a type is a record
     */
-   bool is_record() const
+   bool is_struct() const
    {
       return base_type == GLSL_TYPE_STRUCT;
    }
@@ -618,12 +1043,29 @@ struct glsl_type {
       return size;
    }
 
+   /**
+    * Return bit size for this type.
+    */
+   unsigned bit_size() const
+   {
+      return glsl_base_type_bit_size(this->base_type);
+   }
+
+
+   /**
+    * Query whether or not a type is an atomic_uint.
+    */
+   bool is_atomic_uint() const
+   {
+      return base_type == GLSL_TYPE_ATOMIC_UINT;
+   }
+
    /**
     * Return the amount of atomic counter storage required for a type.
     */
    unsigned atomic_size() const
    {
-      if (base_type == GLSL_TYPE_ATOMIC_UINT)
+      if (is_atomic_uint())
          return ATOMIC_COUNTER_SIZE;
       else if (is_array())
          return length * fields.array->atomic_size();
@@ -653,9 +1095,13 @@ struct glsl_type {
     */
    const glsl_type *row_type() const
    {
-      return is_matrix()
-        ? get_instance(base_type, matrix_columns, 1)
-        : error_type;
+      if (!is_matrix())
+         return error_type;
+
+      if (explicit_stride && !interface_row_major)
+         return get_instance(base_type, matrix_columns, 1, explicit_stride);
+      else
+         return get_instance(base_type, matrix_columns, 1);
    }
 
    /**
@@ -667,9 +1113,24 @@ struct glsl_type {
     */
    const glsl_type *column_type() const
    {
-      return is_matrix()
-        ? get_instance(base_type, vector_elements, 1)
-        : error_type;
+      if (!is_matrix())
+         return error_type;
+
+      if (interface_row_major) {
+         /* If we're row-major, the vector element stride is the same as the
+          * matrix stride and we have no alignment (i.e. component-aligned).
+          */
+         return get_instance(base_type, vector_elements, 1,
+                             explicit_stride, false, 0);
+      } else {
+         /* Otherwise, the vector is tightly packed (stride=0).  For
+          * alignment, we treat a matrix as an array of columns make the same
+          * assumption that the alignment of the column is the same as the
+          * alignment of the whole matrix.
+          */
+         return get_instance(base_type, vector_elements, 1,
+                             0, false, explicit_alignment);
+      }
    }
 
    /**
@@ -716,59 +1177,121 @@ struct glsl_type {
     *
     * Note that this is often different than actual coordinate type used in
     * a texturing built-in function, since those pack additional values (such
-    * as the shadow comparitor or projector) into the coordinate type.
+    * as the shadow comparator or projector) into the coordinate type.
     */
    int coordinate_components() const;
 
+   /**
+    * Compares whether this type matches another type without taking into
+    * account the precision in structures.
+    *
+    * This is applied recursively so that structures containing structure
+    * members can also ignore the precision.
+    */
+   bool compare_no_precision(const glsl_type *b) const;
+
    /**
     * Compare a record type against another record type.
     *
-    * This is useful for matching record types declared across shader stages.
+    * This is useful for matching record types declared on the same shader
+    * stage as well as across different shader stages.
+    * The option to not match name is needed for matching record types
+    * declared across different shader stages.
+    * The option to not match locations is to deal with places where the
+    * same struct is defined in a block which has a location set on it.
     */
-   bool record_compare(const glsl_type *b) const;
+   bool record_compare(const glsl_type *b, bool match_name,
+                       bool match_locations = true,
+                       bool match_precision = true) const;
 
-private:
+   /**
+    * Get the type interface packing.
+    */
+   enum glsl_interface_packing get_interface_packing() const
+   {
+      return (enum glsl_interface_packing)interface_packing;
+   }
 
-   static mtx_t mutex;
+   /**
+    * Get the type interface packing used internally. For shared and packing
+    * layouts this is implementation defined.
+    */
+   enum glsl_interface_packing get_internal_ifc_packing(bool std430_supported) const
+   {
+      enum glsl_interface_packing packing = this->get_interface_packing();
+      if (packing == GLSL_INTERFACE_PACKING_STD140 ||
+          (!std430_supported &&
+           (packing == GLSL_INTERFACE_PACKING_SHARED ||
+            packing == GLSL_INTERFACE_PACKING_PACKED))) {
+         return GLSL_INTERFACE_PACKING_STD140;
+      } else {
+         assert(packing == GLSL_INTERFACE_PACKING_STD430 ||
+                (std430_supported &&
+                 (packing == GLSL_INTERFACE_PACKING_SHARED ||
+                  packing == GLSL_INTERFACE_PACKING_PACKED)));
+         return GLSL_INTERFACE_PACKING_STD430;
+      }
+   }
 
    /**
-    * ralloc context for all glsl_type allocations
-    *
-    * Set on the first call to \c glsl_type::new.
+    * Check if the type interface is row major
     */
-   static void *mem_ctx;
+   bool get_interface_row_major() const
+   {
+      return (bool) interface_row_major;
+   }
+
+   ~glsl_type();
+
+private:
+
+   static mtx_t hash_mutex;
 
-   void init_ralloc_type_ctx(void);
+   /**
+    * ralloc context for the type itself.
+    */
+   void *mem_ctx;
 
    /** Constructor for vector and matrix types */
    glsl_type(GLenum gl_type,
-            glsl_base_type base_type, unsigned vector_elements,
-            unsigned matrix_columns, const char *name);
+             glsl_base_type base_type, unsigned vector_elements,
+             unsigned matrix_columns, const char *name,
+             unsigned explicit_stride = 0, bool row_major = false,
+             unsigned explicit_alignment = 0);
 
    /** 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);
+            glsl_base_type type, const char *name);
 
    /** Constructor for record types */
    glsl_type(const glsl_struct_field *fields, unsigned num_fields,
-            const char *name);
+            const char *name, bool packed = false,
+            unsigned explicit_alignment = 0);
 
    /** Constructor for interface types */
    glsl_type(const glsl_struct_field *fields, unsigned num_fields,
-            enum glsl_interface_packing packing, const char *name);
+            enum glsl_interface_packing packing,
+            bool row_major, const char *name);
 
-   /** Constructor for array types */
-   glsl_type(const glsl_type *array, unsigned length);
+   /** Constructor for interface types */
+   glsl_type(const glsl_type *return_type,
+             const glsl_function_param *params, unsigned num_params);
+
+   /** Constructors for array types */
+   glsl_type(const glsl_type *array, unsigned length, unsigned explicit_stride);
 
    /** Constructor for subroutine types */
    glsl_type(const char *name);
 
+   /** Hash table containing the known explicit matrix and vector types. */
+   static struct hash_table *explicit_matrix_types;
+
    /** Hash table containing the known array types. */
    static struct hash_table *array_types;
 
-   /** Hash table containing the known record types. */
-   static struct hash_table *record_types;
+   /** Hash table containing the known struct types. */
+   static struct hash_table *struct_types;
 
    /** Hash table containing the known interface types. */
    static struct hash_table *interface_types;
@@ -776,6 +1299,9 @@ private:
    /** Hash table containing the known subroutine types. */
    static struct hash_table *subroutine_types;
 
+   /** Hash table containing the known function types. */
+   static struct hash_table *function_types;
+
    static bool record_key_compare(const void *a, const void *b);
    static unsigned record_key_hash(const void *key);
 
@@ -798,11 +1324,16 @@ private:
     * data.
     */
    /*@{*/
+   friend void glsl_type_singleton_init_or_ref(void);
+   friend void glsl_type_singleton_decref(void);
    friend void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *);
-   friend void _mesa_glsl_release_types(void);
    /*@}*/
 };
 
+#undef DECL_TYPE
+#undef STRUCT_TYPE
+#endif /* __cplusplus */
+
 struct glsl_struct_field {
    const struct glsl_type *type;
    const char *name;
@@ -817,62 +1348,122 @@ struct glsl_struct_field {
    int location;
 
    /**
-    * For interface blocks, the interpolation mode (as in
-    * ir_variable::interpolation).  0 otherwise.
-    */
-   unsigned interpolation:2;
-
-   /**
-    * For interface blocks, 1 if this variable uses centroid interpolation (as
-    * in ir_variable::centroid).  0 otherwise.
+    * For interface blocks, members may have an explicit byte offset
+    * specified; -1 otherwise. Also used for xfb_offset layout qualifier.
+    *
+    * Unless used for xfb_offset this field is ignored for structs.
     */
-   unsigned centroid:1;
+   int offset;
 
    /**
-    * For interface blocks, 1 if this variable uses sample interpolation (as
-    * in ir_variable::sample). 0 otherwise.
+    * For interface blocks, members may define a transform feedback buffer;
+    * -1 otherwise.
     */
-   unsigned sample:1;
+   int xfb_buffer;
 
    /**
-    * Layout of the matrix.  Uses glsl_matrix_layout values.
+    * For interface blocks, members may define a transform feedback stride;
+    * -1 otherwise.
     */
-   unsigned matrix_layout:2;
-
+   int xfb_stride;
    /**
-    * For interface blocks, 1 if this variable is a per-patch input or output
-    * (as in ir_variable::patch). 0 otherwise.
+    * Layout format, applicable to image variables only.
     */
-   unsigned patch:1;
+   enum pipe_format image_format;
 
-   /**
-    * Precision qualifier
-    */
-   unsigned precision:2;
-
-   /**
-    * Image qualifiers, applicable to buffer variables defined in shader
-    * storage buffer objects (SSBOs)
-    */
-   unsigned image_read_only:1;
-   unsigned image_write_only:1;
-   unsigned image_coherent:1;
-   unsigned image_volatile:1;
-   unsigned image_restrict:1;
+   union {
+      struct {
+         /**
+          * For interface blocks, the interpolation mode (as in
+          * ir_variable::interpolation).  0 otherwise.
+          */
+         unsigned interpolation:3;
+
+         /**
+          * For interface blocks, 1 if this variable uses centroid interpolation (as
+          * 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, 1 if this variable is a per-patch input or output
+          * (as in ir_variable::patch). 0 otherwise.
+          */
+         unsigned patch:1;
+
+         /**
+          * Precision qualifier
+          */
+         unsigned precision:2;
+
+         /**
+          * Memory qualifiers, applicable to buffer variables defined in shader
+          * storage buffer objects (SSBOs)
+          */
+         unsigned memory_read_only:1;
+         unsigned memory_write_only:1;
+         unsigned memory_coherent:1;
+         unsigned memory_volatile:1;
+         unsigned memory_restrict:1;
+
+         /**
+          * Any of the xfb_* qualifiers trigger the shader to be in transform
+          * feedback mode so we need to keep track of whether the buffer was
+          * explicitly set or if its just been assigned the default global value.
+          */
+         unsigned explicit_xfb_buffer:1;
+
+         unsigned implicit_sized_array:1;
+      };
+      unsigned flags;
+   };
+#ifdef __cplusplus
+#define DEFAULT_CONSTRUCTORS(_type, _name)                  \
+   type(_type), name(_name), location(-1), offset(-1), xfb_buffer(0),   \
+   xfb_stride(0), image_format(PIPE_FORMAT_NONE), flags(0) \
+
+   glsl_struct_field(const struct glsl_type *_type,
+                     int _precision,
+                     const char *_name)
+      : DEFAULT_CONSTRUCTORS(_type, _name)
+   {
+      matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
+      precision = _precision;
+   }
 
    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),
-        precision(GLSL_PRECISION_NONE), image_read_only(0), image_write_only(0),
-        image_coherent(0), image_volatile(0), image_restrict(0)
+      : DEFAULT_CONSTRUCTORS(_type, _name)
    {
-      /* empty */
+      matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
+      precision = GLSL_PRECISION_NONE;
    }
 
    glsl_struct_field()
+      : DEFAULT_CONSTRUCTORS(NULL, NULL)
    {
-      /* empty */
+      matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
+      precision = GLSL_PRECISION_NONE;
    }
+#undef DEFAULT_CONSTRUCTORS
+#endif
+};
+
+struct glsl_function_param {
+   const struct glsl_type *type;
+
+   bool in;
+   bool out;
 };
 
 static inline unsigned int
@@ -881,8 +1472,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 */