[Mesa-dev] [PATCH 2/4] glsl: Refactor ast_function.cpp:type_compare() into a glsl_type method

Chad Versace chad at chad-versace.us
Tue Jul 26 23:36:00 PDT 2011


On a subsequent commit, ast_function_expression::hir() will need access to
type_compare(), but it is defined in a different file.  So refactor
type_compare() into glsl_type::implicit_conversion_compare().

CC: Ian Romanick <ian.d.romanick at intel.com>
Signed-off-by: Chad Versace <chad at chad-versace.us>
---
 src/glsl/glsl_types.cpp  |  304 ++++++++++++++++++++++------------------------
 src/glsl/glsl_types.h    |   11 ++
 src/glsl/ir_function.cpp |   71 +----------
 3 files changed, 166 insertions(+), 220 deletions(-)

diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index a5e21bb..752c1af 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -36,84 +36,64 @@ hash_table *glsl_type::array_types = NULL;
 hash_table *glsl_type::record_types = NULL;
 void *glsl_type::mem_ctx = NULL;
 
-void
-glsl_type::init_ralloc_type_ctx(void)
-{
+void glsl_type::init_ralloc_type_ctx(void) {
    if (glsl_type::mem_ctx == NULL) {
       glsl_type::mem_ctx = ralloc_autofree_context();
       assert(glsl_type::mem_ctx != NULL);
    }
 }
 
-glsl_type::glsl_type(GLenum gl_type,
-		     glsl_base_type base_type, unsigned vector_elements,
-		     unsigned matrix_columns, const char *name) :
-   gl_type(gl_type),
-   base_type(base_type),
-   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampler_type(0),
-   vector_elements(vector_elements), matrix_columns(matrix_columns),
-   length(0)
-{
+glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type,
+      unsigned vector_elements, unsigned matrix_columns, const char *name) :
+      gl_type(gl_type), base_type(base_type), sampler_dimensionality(0), sampler_shadow(
+	    0), sampler_array(0), sampler_type(0), vector_elements(
+	    vector_elements), matrix_columns(matrix_columns), length(0) {
    init_ralloc_type_ctx();
    this->name = ralloc_strdup(this->mem_ctx, name);
    /* Neither dimension is zero or both dimensions are zero.
     */
    assert((vector_elements == 0) == (matrix_columns == 0));
-   memset(& fields, 0, sizeof(fields));
+   memset(&fields, 0, sizeof(fields));
 }
 
-glsl_type::glsl_type(GLenum gl_type,
-		     enum glsl_sampler_dim dim, bool shadow, bool array,
-		     unsigned type, const char *name) :
-   gl_type(gl_type),
-   base_type(GLSL_TYPE_SAMPLER),
-   sampler_dimensionality(dim), sampler_shadow(shadow),
-   sampler_array(array), sampler_type(type),
-   vector_elements(0), matrix_columns(0),
-   length(0)
-{
+glsl_type::glsl_type(GLenum gl_type, enum glsl_sampler_dim dim, bool shadow,
+      bool array, unsigned type, const char *name) :
+      gl_type(gl_type), base_type(GLSL_TYPE_SAMPLER), sampler_dimensionality(
+	    dim), sampler_shadow(shadow), sampler_array(array), sampler_type(
+	    type), vector_elements(0), matrix_columns(0), length(0) {
    init_ralloc_type_ctx();
    this->name = ralloc_strdup(this->mem_ctx, name);
-   memset(& fields, 0, sizeof(fields));
+   memset(&fields, 0, sizeof(fields));
 }
 
 glsl_type::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),
-   length(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), length(
+	    num_fields) {
    unsigned int i;
 
    init_ralloc_type_ctx();
    this->name = ralloc_strdup(this->mem_ctx, name);
    this->fields.structure = ralloc_array(this->mem_ctx,
-					 glsl_struct_field, length);
+	 glsl_struct_field, length);
    for (i = 0; i < length; i++) {
       this->fields.structure[i].type = fields[i].type;
       this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
-						     fields[i].name);
+	    fields[i].name);
    }
 }
 
-static void
-add_types_to_symbol_table(glsl_symbol_table *symtab,
-			  const struct glsl_type *types,
-			  unsigned num_types, bool warn)
-{
+static void add_types_to_symbol_table(glsl_symbol_table *symtab,
+      const struct glsl_type *types, unsigned num_types, bool warn) {
    (void) warn;
 
    for (unsigned i = 0; i < num_types; i++) {
-      symtab->add_type(types[i].name, & types[i]);
+      symtab->add_type(types[i].name, &types[i]);
    }
 }
 
-bool
-glsl_type::contains_sampler() const
-{
+bool glsl_type::contains_sampler() const {
    if (this->is_array()) {
       return this->fields.array->contains_sampler();
    } else if (this->is_record()) {
@@ -127,84 +107,57 @@ glsl_type::contains_sampler() const
    }
 }
 
-void
-glsl_type::generate_100ES_types(glsl_symbol_table *symtab)
-{
+void glsl_type::generate_100ES_types(glsl_symbol_table *symtab) {
    add_types_to_symbol_table(symtab, builtin_core_types,
-			     Elements(builtin_core_types),
-			     false);
+	 Elements(builtin_core_types), false);
    add_types_to_symbol_table(symtab, builtin_structure_types,
-			     Elements(builtin_structure_types),
-			     false);
+	 Elements(builtin_structure_types), false);
    add_types_to_symbol_table(symtab, void_type, 1, false);
 }
 
-void
-glsl_type::generate_110_types(glsl_symbol_table *symtab)
-{
+void glsl_type::generate_110_types(glsl_symbol_table *symtab) {
    generate_100ES_types(symtab);
 
    add_types_to_symbol_table(symtab, builtin_110_types,
-			     Elements(builtin_110_types),
-			     false);
+	 Elements(builtin_110_types), false);
    add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false);
    add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
-			     Elements(builtin_110_deprecated_structure_types),
-			     false);
+	 Elements(builtin_110_deprecated_structure_types), false);
 }
 
-
-void
-glsl_type::generate_120_types(glsl_symbol_table *symtab)
-{
+void glsl_type::generate_120_types(glsl_symbol_table *symtab) {
    generate_110_types(symtab);
 
    add_types_to_symbol_table(symtab, builtin_120_types,
-			     Elements(builtin_120_types), false);
+	 Elements(builtin_120_types), false);
 }
 
-
-void
-glsl_type::generate_130_types(glsl_symbol_table *symtab)
-{
+void glsl_type::generate_130_types(glsl_symbol_table *symtab) {
    generate_120_types(symtab);
 
    add_types_to_symbol_table(symtab, builtin_130_types,
-			     Elements(builtin_130_types), false);
+	 Elements(builtin_130_types), false);
    generate_EXT_texture_array_types(symtab, false);
 }
 
-
-void
-glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
-						bool warn)
-{
+void glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
+      bool warn) {
    add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
-			     Elements(builtin_ARB_texture_rectangle_types),
-			     warn);
+	 Elements(builtin_ARB_texture_rectangle_types), warn);
 }
 
-
-void
-glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
-					    bool warn)
-{
+void glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
+      bool warn) {
    add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
-			     Elements(builtin_EXT_texture_array_types),
-			     warn);
+	 Elements(builtin_EXT_texture_array_types), warn);
 }
 
-
-void
-glsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab, bool warn)
-{
+void glsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab,
+      bool warn) {
    add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn);
 }
 
-
-void
-_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
-{
+void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) {
    switch (state->language_version) {
    case 100:
       assert(state->es_shader);
@@ -226,23 +179,21 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
 
    if (state->ARB_texture_rectangle_enable) {
       glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
-					   state->ARB_texture_rectangle_warn);
+	    state->ARB_texture_rectangle_warn);
    }
    if (state->OES_texture_3D_enable && state->language_version == 100) {
       glsl_type::generate_OES_texture_3D_types(state->symbols,
-					       state->OES_texture_3D_warn);
+	    state->OES_texture_3D_warn);
    }
 
    if (state->EXT_texture_array_enable && state->language_version < 130) {
       // These are already included in 130; don't create twice.
       glsl_type::generate_EXT_texture_array_types(state->symbols,
-				       state->EXT_texture_array_warn);
+	    state->EXT_texture_array_warn);
    }
 }
 
-
-const glsl_type *glsl_type::get_base_type() const
-{
+const glsl_type *glsl_type::get_base_type() const {
    switch (base_type) {
    case GLSL_TYPE_UINT:
       return uint_type;
@@ -257,10 +208,7 @@ const glsl_type *glsl_type::get_base_type() const
    }
 }
 
-
-void
-_mesa_glsl_release_types(void)
-{
+void _mesa_glsl_release_types(void) {
    if (glsl_type::array_types != NULL) {
       hash_table_dtor(glsl_type::array_types);
       glsl_type::array_types = NULL;
@@ -272,14 +220,10 @@ _mesa_glsl_release_types(void)
    }
 }
 
-
 glsl_type::glsl_type(const glsl_type *array, unsigned length) :
-   base_type(GLSL_TYPE_ARRAY),
-   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampler_type(0),
-   vector_elements(0), matrix_columns(0),
-   name(NULL), length(length)
-{
+      base_type(GLSL_TYPE_ARRAY), sampler_dimensionality(0), sampler_shadow(0), sampler_array(
+	    0), sampler_type(0), vector_elements(0), matrix_columns(0), name(
+	    NULL), length(length) {
    this->fields.array = array;
    /* Inherit the gl type of the base. The GL type is used for
     * uniform/statevar handling in Mesa and the arrayness of the type
@@ -292,7 +236,7 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) :
     * NUL.
     */
    const unsigned name_length = strlen(array->name) + 10 + 3;
-   char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
+   char * const n = (char *) ralloc_size(this->mem_ctx, name_length);
 
    if (length == 0)
       snprintf(n, name_length, "%s[]", array->name);
@@ -302,10 +246,8 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) :
    this->name = n;
 }
 
-
 const glsl_type *
-glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
-{
+glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) {
    if (base_type == GLSL_TYPE_VOID)
       return void_type;
 
@@ -343,16 +285,26 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
 #define IDX(c,r) (((c-1)*3) + (r-1))
 
       switch (IDX(columns, rows)) {
-      case IDX(2,2): return mat2_type;
-      case IDX(2,3): return mat2x3_type;
-      case IDX(2,4): return mat2x4_type;
-      case IDX(3,2): return mat3x2_type;
-      case IDX(3,3): return mat3_type;
-      case IDX(3,4): return mat3x4_type;
-      case IDX(4,2): return mat4x2_type;
-      case IDX(4,3): return mat4x3_type;
-      case IDX(4,4): return mat4_type;
-      default: return error_type;
+      case IDX(2,2):
+	 return mat2_type;
+      case IDX(2,3):
+	 return mat2x3_type;
+      case IDX(2,4):
+	 return mat2x4_type;
+      case IDX(3,2):
+	 return mat3x2_type;
+      case IDX(3,3):
+	 return mat3_type;
+      case IDX(3,4):
+	 return mat3x4_type;
+      case IDX(4,2):
+	 return mat4x2_type;
+      case IDX(4,3):
+	 return mat4x3_type;
+      case IDX(4,4):
+	 return mat4_type;
+      default:
+	 return error_type;
       }
    }
 
@@ -360,14 +312,12 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
    return error_type;
 }
 
-
 const glsl_type *
-glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
-{
+glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) {
 
    if (array_types == NULL) {
       array_types = hash_table_ctor(64, hash_table_string_hash,
-				    hash_table_string_compare);
+	    hash_table_string_compare);
    }
 
    /* Generate a name using the base type pointer in the key.  This is
@@ -392,12 +342,9 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
    return t;
 }
 
-
-int
-glsl_type::record_key_compare(const void *a, const void *b)
-{
-   const glsl_type *const key1 = (glsl_type *) a;
-   const glsl_type *const key2 = (glsl_type *) b;
+int glsl_type::record_key_compare(const void *a, const void *b) {
+   const glsl_type * const key1 = (glsl_type *) a;
+   const glsl_type * const key2 = (glsl_type *) b;
 
    /* Return zero is the types match (there is zero difference) or non-zero
     * otherwise.
@@ -411,19 +358,16 @@ glsl_type::record_key_compare(const void *a, const void *b)
    for (unsigned i = 0; i < key1->length; i++) {
       if (key1->fields.structure[i].type != key2->fields.structure[i].type)
 	 return 1;
-      if (strcmp(key1->fields.structure[i].name,
-		 key2->fields.structure[i].name) != 0)
+      if (strcmp(key1->fields.structure[i].name, key2->fields.structure[i].name)
+	    != 0)
 	 return 1;
    }
 
    return 0;
 }
 
-
-unsigned
-glsl_type::record_key_hash(const void *a)
-{
-   const glsl_type *const key = (glsl_type *) a;
+unsigned glsl_type::record_key_hash(const void *a) {
+   const glsl_type * const key = (glsl_type *) a;
    char hash_key[128];
    unsigned size = 0;
 
@@ -433,26 +377,23 @@ glsl_type::record_key_hash(const void *a)
       if (size >= sizeof(hash_key))
 	 break;
 
-      size += snprintf(& hash_key[size], sizeof(hash_key) - size,
-		       "%p", (void *) key->fields.structure[i].type);
+      size += snprintf(&hash_key[size], sizeof(hash_key) - size, "%p",
+	    (void *) key->fields.structure[i].type);
    }
 
-   return hash_table_string_hash(& hash_key);
+   return hash_table_string_hash(&hash_key);
 }
 
-
 const glsl_type *
 glsl_type::get_record_instance(const glsl_struct_field *fields,
-			       unsigned num_fields,
-			       const char *name)
-{
+      unsigned num_fields, const char *name) {
    const glsl_type key(fields, num_fields, name);
 
    if (record_types == NULL) {
       record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
    }
 
-   const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
+   const glsl_type *t = (glsl_type *) hash_table_find(record_types, &key);
    if (t == NULL) {
       t = new glsl_type(fields, num_fields, name);
 
@@ -466,10 +407,8 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
    return t;
 }
 
-
 const glsl_type *
-glsl_type::field_type(const char *name) const
-{
+glsl_type::field_type(const char *name) const {
    if (this->base_type != GLSL_TYPE_STRUCT)
       return error_type;
 
@@ -481,10 +420,7 @@ glsl_type::field_type(const char *name) const
    return error_type;
 }
 
-
-int
-glsl_type::field_index(const char *name) const
-{
+int glsl_type::field_index(const char *name) const {
    if (this->base_type != GLSL_TYPE_STRUCT)
       return -1;
 
@@ -496,10 +432,7 @@ glsl_type::field_index(const char *name) const
    return -1;
 }
 
-
-unsigned
-glsl_type::component_slots() const
-{
+unsigned glsl_type::component_slots() const {
    switch (this->base_type) {
    case GLSL_TYPE_UINT:
    case GLSL_TYPE_INT:
@@ -523,3 +456,62 @@ glsl_type::component_slots() const
       return 0;
    }
 }
+
+int glsl_type::implicit_conversion_compare(const glsl_type *desired) const {
+   /* If the types are the same, they trivially match. */
+   if (this == desired)
+      return 0;
+
+   switch (desired->base_type) {
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_BOOL:
+      /* There is no implicit conversion to or from integer types or bool. */
+      if ((this->is_integer() != desired->is_integer())
+	  || (this->is_boolean() != desired->is_boolean()))
+	 return -1;
+
+      /* FALLTHROUGH */
+
+   case GLSL_TYPE_FLOAT:
+      if ((this->vector_elements != desired->vector_elements)
+	  || (this->matrix_columns != desired->matrix_columns))
+	 return -1;
+
+      return 1;
+
+   case GLSL_TYPE_SAMPLER:
+   case GLSL_TYPE_STRUCT:
+      /* Samplers and structures must match exactly. */
+      return -1;
+
+   case GLSL_TYPE_ARRAY: {
+      if ((this->base_type != GLSL_TYPE_ARRAY)
+	    || (this->length != desired->length))
+	 return -1;
+
+      /* From GLSL 1.50 spec, page 27 (page 33 of the PDF):
+       *    "There are no implicit array or structure conversions."
+       *
+       * If the comparison of the array element types detects that a conversion
+       * would be required, the array types do not match.
+       */
+      const glsl_type *this2 = this->fields.array;
+      const glsl_type *desired2 = desired->fields.array;
+      if (this2->implicit_conversion_compare(desired2) == 0)
+	 return 0;
+      else
+	 return -1;
+   }
+
+   case GLSL_TYPE_VOID:
+   case GLSL_TYPE_ERROR:
+   default:
+      /* These are all error conditions.  It is invalid for a parameter to
+       * a function to be declared as error, void, or a function.
+       */
+      return -1;
+   }
+
+   assert(0);
+}
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index 87f57e7..d791eee 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -224,6 +224,17 @@ struct glsl_type {
     */
    unsigned component_slots() const;
 
+   /**
+    * \brief Check if an implicit type conversion is possible or necessary.
+    *
+    * If the types are identical, so no conversion is necessary, return 0.
+    * If an implicit conversion is legal, return 1.
+    * If an implicit conversion is illegal, return -1.
+    *
+    * See page 20 (26 of the pdf) of the GLSL 1.20 spec, Section 4.1.10 Implicit
+    * Conversions.
+    */
+   int implicit_conversion_compare(const glsl_type *desired) const;
 
    /**
     * Query whether or not a type is a scalar (non-vector and non-matrix).
diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index 6795988..98f9f51 100644
--- a/src/glsl/ir_function.cpp
+++ b/src/glsl/ir_function.cpp
@@ -24,67 +24,6 @@
 #include "glsl_types.h"
 #include "ir.h"
 
-int
-type_compare(const glsl_type *a, const glsl_type *b)
-{
-   /* If the types are the same, they trivially match.
-    */
-   if (a == b)
-      return 0;
-
-   switch (a->base_type) {
-   case GLSL_TYPE_UINT:
-   case GLSL_TYPE_INT:
-   case GLSL_TYPE_BOOL:
-      /* There is no implicit conversion to or from integer types or bool.
-       */
-      if ((a->is_integer() != b->is_integer())
-	  || (a->is_boolean() != b->is_boolean()))
-	 return -1;
-
-      /* FALLTHROUGH */
-
-   case GLSL_TYPE_FLOAT:
-      if ((a->vector_elements != b->vector_elements)
-	  || (a->matrix_columns != b->matrix_columns))
-	 return -1;
-
-      return 1;
-
-   case GLSL_TYPE_SAMPLER:
-   case GLSL_TYPE_STRUCT:
-      /* Samplers and structures must match exactly.
-       */
-      return -1;
-
-   case GLSL_TYPE_ARRAY:
-      if ((b->base_type != GLSL_TYPE_ARRAY)
-	  || (a->length != b->length))
-	 return -1;
-
-      /* From GLSL 1.50 spec, page 27 (page 33 of the PDF):
-       *    "There are no implicit array or structure conversions."
-       *
-       * If the comparison of the array element types detects that a conversion
-       * would be required, the array types do not match.
-       */
-      return (type_compare(a->fields.array, b->fields.array) == 0) ? 0 : -1;
-
-   case GLSL_TYPE_VOID:
-   case GLSL_TYPE_ERROR:
-   default:
-      /* These are all error conditions.  It is invalid for a parameter to
-       * a function to be declared as error, void, or a function.
-       */
-      return -1;
-   }
-
-   /* This point should be unreachable.
-    */
-   assert(0);
-}
-
-
 /**
  * Called by matching_signature().
  *
@@ -131,11 +70,11 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b)
 
       case ir_var_const_in:
       case ir_var_in:
-	 score = type_compare(param->type, actual->type);
+	 score = actual->type->implicit_conversion_compare(param->type);
 	 break;
 
       case ir_var_out:
-	 score = type_compare(actual->type, param->type);
+	 score = actual->type->implicit_conversion_compare(actual->type);
 	 break;
 
       case ir_var_inout:
@@ -143,7 +82,11 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b)
 	  * there is int -> float but no float -> int), inout parameters must
 	  * be exact matches.
 	  */
-	 score = (type_compare(actual->type, param->type) == 0) ? 0 : -1;
+	 if (param->type->implicit_conversion_compare(actual->type) == 0)
+	    score = 0;
+	 else
+	    score = -1;
+
 	 break;
 
       default:
-- 
1.7.6



More information about the mesa-dev mailing list