glsl: Optimize ir_triop_lrp(x, y, a) with a = 0.0f or 1.0f
[mesa.git] / src / glsl / glsl_types.h
index 39e6ac970aa6ff527453c11986c8bef24a5c9a76..8cfd8dd021d50eed5065e61f23a262df084d454f 100644 (file)
 #ifndef GLSL_TYPES_H
 #define GLSL_TYPES_H
 
-#include <cstring>
-#include <cassert>
+#include <string.h>
+#include <assert.h>
+#include "main/mtypes.h" /* for gl_texture_index, C++'s enum rules are broken */
 
+#ifdef __cplusplus
 extern "C" {
-#include <talloc.h>
+#endif
+
+struct _mesa_glsl_parse_state;
+struct glsl_symbol_table;
+
+extern void
+_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
+
+extern void
+_mesa_glsl_release_types(void);
+
+#ifdef __cplusplus
 }
+#endif
 
-#define GLSL_TYPE_UINT          0
-#define GLSL_TYPE_INT           1
-#define GLSL_TYPE_FLOAT         2
-#define GLSL_TYPE_BOOL          3
-#define GLSL_TYPE_SAMPLER       4
-#define GLSL_TYPE_STRUCT        5
-#define GLSL_TYPE_ARRAY         6
-#define GLSL_TYPE_FUNCTION      7
-#define GLSL_TYPE_VOID          8
-#define GLSL_TYPE_ERROR         9
+enum glsl_base_type {
+   GLSL_TYPE_UINT = 0,
+   GLSL_TYPE_INT,
+   GLSL_TYPE_FLOAT,
+   GLSL_TYPE_BOOL,
+   GLSL_TYPE_SAMPLER,
+   GLSL_TYPE_STRUCT,
+   GLSL_TYPE_INTERFACE,
+   GLSL_TYPE_ARRAY,
+   GLSL_TYPE_VOID,
+   GLSL_TYPE_ERROR
+};
 
 enum glsl_sampler_dim {
    GLSL_SAMPLER_DIM_1D = 0,
@@ -50,38 +66,55 @@ enum glsl_sampler_dim {
    GLSL_SAMPLER_DIM_3D,
    GLSL_SAMPLER_DIM_CUBE,
    GLSL_SAMPLER_DIM_RECT,
-   GLSL_SAMPLER_DIM_BUF
+   GLSL_SAMPLER_DIM_BUF,
+   GLSL_SAMPLER_DIM_EXTERNAL
 };
 
+enum glsl_interface_packing {
+   GLSL_INTERFACE_PACKING_STD140,
+   GLSL_INTERFACE_PACKING_SHARED,
+   GLSL_INTERFACE_PACKING_PACKED
+};
+
+#ifdef __cplusplus
+#include "GL/gl.h"
+#include "ralloc.h"
 
 struct glsl_type {
-   unsigned base_type:4;
+   GLenum gl_type;
+   glsl_base_type base_type;
 
-   unsigned sampler_dimensionality:3;
+   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,
                                * and \c GLSL_TYPE_UINT are valid.
                                */
+   unsigned interface_packing:2;
 
-   /* Callers of this talloc-based new need not call delete. It's
-    * easier to just talloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
+   /* 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)
    {
+      if (glsl_type::mem_ctx == NULL) {
+        glsl_type::mem_ctx = ralloc_context(NULL);
+        assert(glsl_type::mem_ctx != NULL);
+      }
+
       void *type;
 
-      type = talloc_size(ctx, size);
+      type = ralloc_size(glsl_type::mem_ctx, size);
       assert(type != NULL);
 
       return type;
    }
 
    /* If the user *does* call delete, that's OK, we will just
-    * talloc_free in that case. */
+    * ralloc_free in that case. */
    static void operator delete(void *type)
    {
-      talloc_free(type);
+      ralloc_free(type);
    }
 
    /**
@@ -105,13 +138,9 @@ struct glsl_type {
 
    /**
     * For \c GLSL_TYPE_ARRAY, this is the length of the array.  For
-    * \c GLSL_TYPE_STRUCT, it is the number of elements in the structure and
-    * the number of values pointed to by \c fields.structure (below).
-    *
-    * For \c GLSL_TYPE_FUNCTION, it is the number of parameters to the
-    * function.  The return value from a function is implicitly the first
-    * parameter.  The types of the parameters are stored in
-    * \c fields.parameters (below).
+    * \c GLSL_TYPE_STRUCT or \c GLSL_TYPE_INTERFACE, it is the number of
+    * elements in the structure and the number of values pointed to by
+    * \c fields.structure (below).
     */
    unsigned length;
 
@@ -121,7 +150,7 @@ struct glsl_type {
    union {
       const struct glsl_type *array;            /**< Type of array elements. */
       const struct glsl_type *parameters;       /**< Parameters to function. */
-      const struct glsl_struct_field *structure;/**< List of struct fields. */
+      struct glsl_struct_field *structure;      /**< List of struct fields. */
    } fields;
 
 
@@ -130,15 +159,23 @@ struct glsl_type {
     */
    /*@{*/
    static const glsl_type *const error_type;
+   static const glsl_type *const void_type;
    static const glsl_type *const int_type;
+   static const glsl_type *const ivec2_type;
+   static const glsl_type *const ivec3_type;
    static const glsl_type *const ivec4_type;
    static const glsl_type *const uint_type;
+   static const glsl_type *const uvec2_type;
+   static const glsl_type *const uvec3_type;
    static const glsl_type *const uvec4_type;
    static const glsl_type *const float_type;
    static const glsl_type *const vec2_type;
    static const glsl_type *const vec3_type;
    static const glsl_type *const vec4_type;
    static const glsl_type *const bool_type;
+   static const glsl_type *const bvec2_type;
+   static const glsl_type *const bvec3_type;
+   static const glsl_type *const bvec4_type;
    static const glsl_type *const mat2_type;
    static const glsl_type *const mat2x3_type;
    static const glsl_type *const mat2x4_type;
@@ -151,45 +188,6 @@ struct glsl_type {
    /*@}*/
 
 
-   glsl_type(unsigned base_type, unsigned vector_elements,
-            unsigned matrix_columns, const char *name) :
-      base_type(base_type), 
-      sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-      sampler_type(0),
-      vector_elements(vector_elements), matrix_columns(matrix_columns),
-      name(name),
-      length(0)
-   {
-      /* Neither dimension is zero or both dimensions are zero.
-       */
-      assert((vector_elements == 0) == (matrix_columns == 0));
-      memset(& fields, 0, sizeof(fields));
-   }
-
-   glsl_type(enum glsl_sampler_dim dim, bool shadow, bool array,
-            unsigned type, const char *name) :
-      base_type(GLSL_TYPE_SAMPLER),
-      sampler_dimensionality(dim), sampler_shadow(shadow),
-      sampler_array(array), sampler_type(type),
-      vector_elements(0), matrix_columns(0),
-      name(name),
-      length(0)
-   {
-      memset(& fields, 0, sizeof(fields));
-   }
-
-   glsl_type(const glsl_struct_field *fields, unsigned num_fields,
-            const char *name) :
-      base_type(GLSL_TYPE_STRUCT),
-      sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-      sampler_type(0),
-      vector_elements(0), matrix_columns(0),
-      name(name),
-      length(num_fields)
-   {
-      this->fields.structure = fields;
-   }
-
    /**
     * For numeric and boolean derrived types returns the basic scalar type
     *
@@ -200,6 +198,17 @@ struct glsl_type {
     */
    const glsl_type *get_base_type() const;
 
+   /**
+    * Get the basic scalar type which this type aggregates.
+    *
+    * If the type is a numeric or boolean scalar, vector, or matrix, or an
+    * array of any of those, this function gets the scalar type of the
+    * individual components.  For structs and arrays of structs, this function
+    * returns the struct type.  For samplers and arrays of samplers, this
+    * function returns the sampler type.
+    */
+   const glsl_type *get_scalar_type() const;
+
    /**
     * Query the type of elements in an array
     *
@@ -221,14 +230,23 @@ struct glsl_type {
    /**
     * Get the instance of an array type
     */
-   static const glsl_type *get_array_instance(void *ctx,
-                                             const glsl_type *base,
+   static const glsl_type *get_array_instance(const glsl_type *base,
                                              unsigned elements);
 
    /**
-    * Generate the constructor for this type and add it to the symbol table
+    * Get the instance of a record type
+    */
+   static const glsl_type *get_record_instance(const glsl_struct_field *fields,
+                                              unsigned num_fields,
+                                              const char *name);
+
+   /**
+    * Get the instance of an interface block type
     */
-   class ir_function *generate_constructor(class glsl_symbol_table *) const;
+   static const glsl_type *get_interface_instance(const glsl_struct_field *fields,
+                                                 unsigned num_fields,
+                                                 enum glsl_interface_packing packing,
+                                                 const char *name);
 
    /**
     * Query the total number of scalars that make up a scalar, vector or matrix
@@ -246,6 +264,54 @@ struct glsl_type {
     */
    unsigned component_slots() const;
 
+   /**
+    * Alignment in bytes of the start of this type in a std140 uniform
+    * block.
+    */
+   unsigned std140_base_alignment(bool row_major) const;
+
+   /** Size in bytes of this type in a std140 uniform block.
+    *
+    * Note that this is not GL_UNIFORM_SIZE (which is the number of
+    * elements in the array)
+    */
+   unsigned std140_size(bool row_major) const;
+
+   /**
+    * \brief Can this type be implicitly converted to another?
+    *
+    * \return True if the types are identical or if this type can be converted
+    *         to \c desired according to Section 4.1.10 of the GLSL spec.
+    *
+    * \verbatim
+    * From page 25 (31 of the pdf) of the GLSL 1.50 spec, Section 4.1.10
+    * Implicit Conversions:
+    *
+    *     In some situations, an expression and its type will be implicitly
+    *     converted to a different type. The following table shows all allowed
+    *     implicit conversions:
+    *
+    *     Type of expression | Can be implicitly converted to
+    *     --------------------------------------------------
+    *     int                  float
+    *     uint
+    *
+    *     ivec2                vec2
+    *     uvec2
+    *
+    *     ivec3                vec3
+    *     uvec3
+    *
+    *     ivec4                vec4
+    *     uvec4
+    *
+    *     There are no implicit array or structure conversions. For example,
+    *     an array of int cannot be implicitly converted to an array of float.
+    *     There are no implicit conversions between signed and unsigned
+    *     integers.
+    * \endverbatim
+    */
+   bool can_implicitly_convert_to(const glsl_type *desired) const;
 
    /**
     * Query whether or not a type is a scalar (non-vector and non-matrix).
@@ -293,6 +359,12 @@ struct glsl_type {
       return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT);
    }
 
+   /**
+    * Query whether or not type is an integral type, or for struct and array
+    * types, contains an integral type.
+    */
+   bool contains_integer() const;
+
    /**
     * Query whether or not a type is a float type
     */
@@ -317,6 +389,17 @@ struct glsl_type {
       return base_type == GLSL_TYPE_SAMPLER;
    }
 
+   /**
+    * Query whether or not type is a sampler, or for struct and array
+    * types, contains a sampler.
+    */
+   bool contains_sampler() const;
+
+   /**
+    * Get the Mesa texture target index for a sampler type.
+    */
+   gl_texture_index sampler_index() const;
+
    /**
     * Query whether or not a type is an array
     */
@@ -333,6 +416,14 @@ struct glsl_type {
       return base_type == GLSL_TYPE_STRUCT;
    }
 
+   /**
+    * Query whether or not a type is an interface
+    */
+   bool is_interface() const
+   {
+      return base_type == GLSL_TYPE_INTERFACE;
+   }
+
    /**
     * Query whether or not a type is the void type singleton.
     */
@@ -409,37 +500,119 @@ struct glsl_type {
 
 private:
    /**
-    * Constructor for array types
+    * ralloc context for all glsl_type allocations
+    *
+    * Set on the first call to \c glsl_type::new.
     */
-   glsl_type(void *ctx, const glsl_type *array, unsigned length);
+   static void *mem_ctx;
+
+   void init_ralloc_type_ctx(void);
+
+   /** 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);
+
+   /** Constructor for sampler types */
+   glsl_type(GLenum gl_type,
+            enum glsl_sampler_dim dim, bool shadow, bool array,
+            unsigned type, const char *name);
+
+   /** Constructor for record types */
+   glsl_type(const glsl_struct_field *fields, unsigned num_fields,
+            const char *name);
+
+   /** Constructor for interface types */
+   glsl_type(const glsl_struct_field *fields, unsigned num_fields,
+            enum glsl_interface_packing packing, const char *name);
+
+   /** Constructor for array types */
+   glsl_type(const glsl_type *array, unsigned length);
 
    /** Hash table containing the known array types. */
    static struct hash_table *array_types;
 
-   static int array_key_compare(const void *a, const void *b);
-   static unsigned array_key_hash(const void *key);
+   /** Hash table containing the known record types. */
+   static struct hash_table *record_types;
+
+   /** Hash table containing the known interface types. */
+   static struct hash_table *interface_types;
+
+   static int record_key_compare(const void *a, const void *b);
+   static unsigned record_key_hash(const void *key);
+
+   /**
+    * \name Pointers to various type singletons
+    */
+   /*@{*/
+   static const glsl_type _error_type;
+   static const glsl_type _void_type;
+   static const glsl_type _sampler3D_type;
+   static const glsl_type _samplerCubeShadow_type;
+   static const glsl_type builtin_core_types[];
+   static const glsl_type builtin_structure_types[];
+   static const glsl_type builtin_110_deprecated_structure_types[];
+   static const glsl_type builtin_110_types[];
+   static const glsl_type builtin_120_types[];
+   static const glsl_type builtin_130_types[];
+   static const glsl_type builtin_140_types[];
+   static const glsl_type builtin_ARB_texture_rectangle_types[];
+   static const glsl_type builtin_EXT_texture_array_types[];
+   static const glsl_type builtin_EXT_texture_buffer_object_types[];
+   static const glsl_type builtin_OES_EGL_image_external_types[];
+   static const glsl_type builtin_ARB_texture_cube_map_array_types[];
+   /*@}*/
+
+   /**
+    * \name Methods to populate a symbol table with built-in types.
+    *
+    * \internal
+    * This is one of the truely annoying things about C++.  Methods that are
+    * completely internal and private to a type still have to be advertised to
+    * the world in a public header file.
+    */
+   /*@{*/
+   static void generate_100ES_types(glsl_symbol_table *);
+   static void generate_300ES_types(glsl_symbol_table *);
+   static void generate_110_types(glsl_symbol_table *, bool add_deprecated,
+                                  bool skip_1d);
+   static void generate_120_types(glsl_symbol_table *, bool add_deprecated,
+                                  bool skip_1d);
+   static void generate_130_types(glsl_symbol_table *, bool add_deprecated,
+                                  bool skip_1d);
+   static void generate_140_types(glsl_symbol_table *);
+   static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool);
+   static void generate_EXT_texture_array_types(glsl_symbol_table *, bool);
+   static void generate_OES_texture_3D_types(glsl_symbol_table *, bool);
+   static void generate_OES_EGL_image_external_types(glsl_symbol_table *, bool);
+   static void generate_ARB_texture_cube_map_array_types(glsl_symbol_table *, bool);
+   /*@}*/
+
+   /**
+    * \name Friend functions.
+    *
+    * These functions are friends because they must have C linkage and the
+    * need to call various private methods or access various private static
+    * data.
+    */
+   /*@{*/
+   friend void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *);
+   friend void _mesa_glsl_release_types(void);
+   /*@}*/
 };
 
 struct glsl_struct_field {
    const struct glsl_type *type;
    const char *name;
+   bool row_major;
 };
 
-struct _mesa_glsl_parse_state;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void
-_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
-
-extern void
-_mesa_glsl_initialize_constructors(struct exec_list *instructions,
-                                  struct _mesa_glsl_parse_state *state);
-
-#ifdef __cplusplus
+static inline unsigned int
+glsl_align(unsigned int a, unsigned int align)
+{
+   return (a + align - 1) / align * align;
 }
-#endif
+
+#endif /* __cplusplus */
 
 #endif /* GLSL_TYPES_H */