Add utility function to get the name of a shader target
[mesa.git] / glsl_types.h
index 0375934de9ce5f353e0a30b6018eb926a28c2208..33b1c98158d08aad30a4b6a155689c98a06a4e84 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- c++ -*- */
 /*
  * Copyright © 2009 Intel Corporation
  *
@@ -26,6 +27,7 @@
 #define GLSL_TYPES_H
 
 #include <cstring>
+#include <cassert>
 
 #define GLSL_TYPE_UINT          0
 #define GLSL_TYPE_INT           1
 #define GLSL_TYPE_VOID          8
 #define GLSL_TYPE_ERROR         9
 
-#define is_numeric_base_type(b) \
-   (((b) >= GLSL_TYPE_UINT) && ((b) <= GLSL_TYPE_FLOAT))
-
-#define is_integer_base_type(b) \
-   (((b) == GLSL_TYPE_UINT) || ((b) == GLSL_TYPE_INT))
-
-#define is_error_type(t) ((t)->base_type == GLSL_TYPE_ERROR)
-
 enum glsl_sampler_dim {
    GLSL_SAMPLER_DIM_1D = 0,
    GLSL_SAMPLER_DIM_2D,
@@ -67,8 +61,16 @@ struct glsl_type {
                                * and \c GLSL_TYPE_UINT are valid.
                                */
 
-   unsigned vector_elements:3; /**< 0, 2, 3, or 4 vector elements. */
-   unsigned matrix_rows:3;     /**< 0, 2, 3, or 4 matrix rows. */
+   /**
+    * \name Vector and matrix element counts
+    *
+    * For scalars, each of these values will be 1.  For non-numeric types
+    * 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. */
+   /*@}*/
 
    /**
     * Name of the data type
@@ -100,15 +102,30 @@ struct glsl_type {
    } fields;
 
 
+   /**
+    * \name Pointers to various public type singletons
+    */
+   /*@{*/
+   static const glsl_type *const error_type;
+   static const glsl_type *const int_type;
+   static const glsl_type *const uint_type;
+   static const glsl_type *const float_type;
+   static const glsl_type *const bool_type;
+   /*@}*/
+
+
    glsl_type(unsigned base_type, unsigned vector_elements,
-            unsigned matrix_rows, const char *name) :
+            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_rows(matrix_rows),
+      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));
    }
 
@@ -117,7 +134,7 @@ struct glsl_type {
       base_type(GLSL_TYPE_SAMPLER),
       sampler_dimensionality(dim), sampler_shadow(shadow),
       sampler_array(array), sampler_type(type),
-      vector_elements(0), matrix_rows(0),
+      vector_elements(0), matrix_columns(0),
       name(name),
       length(0)
    {
@@ -129,33 +146,221 @@ struct glsl_type {
       base_type(GLSL_TYPE_STRUCT),
       sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
       sampler_type(0),
-      vector_elements(0), matrix_rows(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
+    *
+    * If the type is a numeric or boolean scalar, vector, or matrix type,
+    * this function gets the scalar type of the individual components.  For
+    * all other types, including arrays of numeric or boolean types, the
+    * error type is returned.
+    */
+   const glsl_type *get_base_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 an array type
+    */
+   static const glsl_type *get_array_instance(const glsl_type *base,
+                                             unsigned elements);
+
+   class ir_function *generate_constructor_prototype(class glsl_symbol_table *)
+      const;
+
+   /**
+    * Query the total number of scalars that make up a scalar, vector or matrix
+    */
+   unsigned components() const
+   {
+      return vector_elements * matrix_columns;
+   }
+
    /**
     * Query whether or not a type is a scalar (non-vector and non-matrix).
     */
    bool is_scalar() const
    {
-      return (vector_elements == 0)
+      return (vector_elements == 1)
         && (base_type >= GLSL_TYPE_UINT)
         && (base_type <= GLSL_TYPE_BOOL);
    }
-};
 
-#define is_glsl_type_vector(t)                 \
-   (((t)->vector_elements > 0)                 \
-    && ((t)->matrix_rows == 0)                 \
-    && ((t)->base_type >= GLSL_TYPE_UINT)      \
-    && ((t)->base_type <= GLSL_TYPE_BOOL))
+   /**
+    * Query whether or not a type is a vector
+    */
+   bool is_vector() const
+   {
+      return (vector_elements > 1)
+        && (matrix_columns == 1)
+        && (base_type >= GLSL_TYPE_UINT)
+        && (base_type <= GLSL_TYPE_BOOL);
+   }
+
+   /**
+    * Query whether or not a type is a matrix
+    */
+   bool is_matrix() const
+   {
+      /* GLSL only has float matrices. */
+      return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT);
+   }
+
+   /**
+    * Query whether or not a type is a non-array numeric type
+    */
+   bool is_numeric() const
+   {
+      return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_FLOAT);
+   }
 
-#define is_glsl_type_matrix(t)                 \
-   (((t)->matrix_rows > 0)                     \
-    && ((t)->base_type == GLSL_TYPE_FLOAT)) /* GLSL only has float matrices. */
+   /**
+    * Query whether or not a type is an integral type
+    */
+   bool is_integer() const
+   {
+      return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT);
+   }
+
+   /**
+    * Query whether or not a type is a float type
+    */
+   bool is_float() const
+   {
+      return base_type == GLSL_TYPE_FLOAT;
+   }
+
+   /**
+    * Query whether or not a type is a non-array boolean type
+    */
+   bool is_boolean() const
+   {
+      return base_type == GLSL_TYPE_BOOL;
+   }
+
+   /**
+    * Query whether or not a type is a sampler
+    */
+   bool is_sampler() const
+   {
+      return base_type == GLSL_TYPE_SAMPLER;
+   }
+
+   /**
+    * Query whether or not a type is an array
+    */
+   bool is_array() const
+   {
+      return base_type == GLSL_TYPE_ARRAY;
+   }
+
+   /**
+    * Query whether or not a type is the void type singleton.
+    */
+   bool is_void() const
+   {
+      return base_type == GLSL_TYPE_VOID;
+   }
+
+   /**
+    * Query whether or not a type is the error type singleton.
+    */
+   bool is_error() const
+   {
+      return base_type == GLSL_TYPE_ERROR;
+   }
+
+   /**
+    * Query the full type of a matrix row
+    *
+    * \return
+    * If the type is not a matrix, \c glsl_type::error_type is returned.
+    * Otherwise a type matching the rows of the matrix is returned.
+    */
+   const glsl_type *row_type() const
+   {
+      return is_matrix()
+        ? get_instance(base_type, matrix_columns, 1)
+        : error_type;
+   }
+
+   /**
+    * Query the full type of a matrix column
+    *
+    * \return
+    * If the type is not a matrix, \c glsl_type::error_type is returned.
+    * Otherwise a type matching the columns of the matrix is returned.
+    */
+   const glsl_type *column_type() const
+   {
+      return is_matrix()
+        ? get_instance(base_type, vector_elements, 1)
+        : error_type;
+   }
+
+   /**
+    * Query the number of elements in an array type
+    *
+    * \return
+    * The number of elements in the array for array types or -1 for non-array
+    * types.  If the number of elements in the array has not yet been declared,
+    * zero is returned.
+    */
+   int array_size() const
+   {
+      return is_array() ? length : -1;
+   }
+
+private:
+   /**
+    * Constructor for array types
+    */
+   glsl_type(const glsl_type *array, unsigned length);
+
+
+   /**
+    * \name Pointers to various private type singletons
+    */
+   /*@{*/
+   static const glsl_type *const mat2_type;
+   static const glsl_type *const mat2x3_type;
+   static const glsl_type *const mat2x4_type;
+   static const glsl_type *const mat3x2_type;
+   static const glsl_type *const mat3_type;
+   static const glsl_type *const mat3x4_type;
+   static const glsl_type *const mat4x2_type;
+   static const glsl_type *const mat4x3_type;
+   static const glsl_type *const mat4_type;
+   /*@}*/
+
+   /** 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);
+};
 
 struct glsl_struct_field {
    const struct glsl_type *type;
@@ -171,14 +376,9 @@ extern "C" {
 extern void
 _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
 
-extern const struct glsl_type *
-_mesa_glsl_get_vector_type(unsigned base_type, unsigned vector_length);
-
-extern const struct glsl_type *const glsl_error_type;
-extern const struct glsl_type *const glsl_int_type;
-extern const struct glsl_type *const glsl_uint_type;
-extern const struct glsl_type *const glsl_float_type;
-extern const struct glsl_type *const glsl_bool_type;
+extern void
+_mesa_glsl_initialize_constructors(struct exec_list *instructions,
+                                  struct _mesa_glsl_parse_state *state);
 
 #ifdef __cplusplus
 }