glsl: tidy up IR after loop unrolling
[mesa.git] / src / compiler / glsl_types.cpp
index 0480bef80ecafc786777ab0f7d166eb8d7322de3..99cc696c19bfa08f0983e655361b7fbec42b5a29 100644 (file)
@@ -28,7 +28,8 @@
 #include "util/hash_table.h"
 
 
-mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP;
+mtx_t glsl_type::mem_mutex = _MTX_INITIALIZER_NP;
+mtx_t glsl_type::hash_mutex = _MTX_INITIALIZER_NP;
 hash_table *glsl_type::array_types = NULL;
 hash_table *glsl_type::record_types = NULL;
 hash_table *glsl_type::interface_types = NULL;
@@ -62,13 +63,13 @@ glsl_type::glsl_type(GLenum gl_type,
    STATIC_ASSERT((unsigned(GLSL_TYPE_INT)   & 3) == unsigned(GLSL_TYPE_INT));
    STATIC_ASSERT((unsigned(GLSL_TYPE_FLOAT) & 3) == unsigned(GLSL_TYPE_FLOAT));
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::mem_mutex);
 
    init_ralloc_type_ctx();
    assert(name != NULL);
    this->name = ralloc_strdup(this->mem_ctx, name);
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::mem_mutex);
 
    /* Neither dimension is zero or both dimensions are zero.
     */
@@ -85,22 +86,17 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type,
    sampler_array(array), sampled_type(type), interface_packing(0),
    interface_row_major(0), length(0)
 {
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::mem_mutex);
 
    init_ralloc_type_ctx();
    assert(name != NULL);
    this->name = ralloc_strdup(this->mem_ctx, name);
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::mem_mutex);
 
    memset(& fields, 0, sizeof(fields));
 
-   if (is_sampler()) {
-      /* Samplers take no storage whatsoever. */
-      matrix_columns = vector_elements = 0;
-   } else {
-      matrix_columns = vector_elements = 1;
-   }
+   matrix_columns = vector_elements = 1;
 }
 
 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
@@ -114,7 +110,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
 {
    unsigned int i;
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::mem_mutex);
 
    init_ralloc_type_ctx();
    assert(name != NULL);
@@ -128,7 +124,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
                                                      fields[i].name);
    }
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::mem_mutex);
 }
 
 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
@@ -144,7 +140,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
 {
    unsigned int i;
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::mem_mutex);
 
    init_ralloc_type_ctx();
    assert(name != NULL);
@@ -157,7 +153,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
                                                      fields[i].name);
    }
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::mem_mutex);
 }
 
 glsl_type::glsl_type(const glsl_type *return_type,
@@ -171,7 +167,7 @@ glsl_type::glsl_type(const glsl_type *return_type,
 {
    unsigned int i;
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::mem_mutex);
 
    init_ralloc_type_ctx();
 
@@ -190,7 +186,7 @@ glsl_type::glsl_type(const glsl_type *return_type,
       this->fields.parameters[i + 1].out = params[i].out;
    }
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::mem_mutex);
 }
 
 glsl_type::glsl_type(const char *subroutine_name) :
@@ -201,12 +197,12 @@ glsl_type::glsl_type(const char *subroutine_name) :
    vector_elements(1), matrix_columns(1),
    length(0)
 {
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::mem_mutex);
 
    init_ralloc_type_ctx();
    assert(subroutine_name != NULL);
    this->name = ralloc_strdup(this->mem_ctx, subroutine_name);
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::mem_mutex);
 }
 
 bool
@@ -225,6 +221,19 @@ glsl_type::contains_sampler() const
    }
 }
 
+bool
+glsl_type::contains_array() const
+{
+   if (this->is_record() || this->is_interface()) {
+      for (unsigned int i = 0; i < this->length; i++) {
+         if (this->fields.structure[i].type->contains_array())
+            return true;
+      }
+      return false;
+   } else {
+      return this->is_array();
+   }
+}
 
 bool
 glsl_type::contains_integer() const
@@ -417,6 +426,16 @@ _mesa_glsl_release_types(void)
       glsl_type::interface_types = NULL;
    }
 
+   if (glsl_type::function_types != NULL) {
+      _mesa_hash_table_destroy(glsl_type::function_types, NULL);
+      glsl_type::function_types = NULL;
+   }
+
+   if (glsl_type::subroutine_types != NULL) {
+      _mesa_hash_table_destroy(glsl_type::subroutine_types, NULL);
+      glsl_type::subroutine_types = NULL;
+   }
+
    ralloc_free(glsl_type::mem_ctx);
    glsl_type::mem_ctx = NULL;
 }
@@ -442,9 +461,9 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) :
     */
    const unsigned name_length = strlen(array->name) + 10 + 3;
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::mem_mutex);
    char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::mem_mutex);
 
    if (length == 0)
       snprintf(n, name_length, "%s[]", array->name);
@@ -864,7 +883,7 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
    char key[128];
    snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::hash_mutex);
 
    if (array_types == NULL) {
       array_types = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
@@ -873,9 +892,7 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
 
    const struct hash_entry *entry = _mesa_hash_table_search(array_types, key);
    if (entry == NULL) {
-      mtx_unlock(&glsl_type::mutex);
       const glsl_type *t = new glsl_type(base, array_size);
-      mtx_lock(&glsl_type::mutex);
 
       entry = _mesa_hash_table_insert(array_types,
                                       ralloc_strdup(mem_ctx, key),
@@ -886,7 +903,7 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
    assert(((glsl_type *) entry->data)->length == array_size);
    assert(((glsl_type *) entry->data)->fields.array == base);
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::hash_mutex);
 
    return (glsl_type *) entry->data;
 }
@@ -910,13 +927,9 @@ glsl_type::record_compare(const glsl_type *b, bool match_locations) const
     *     type definitions, and field names to be considered the same type."
     *
     * GLSL ES behaves the same (Ver 1.00 Sec 4.2.4, Ver 3.00 Sec 4.2.5).
-    *
-    * Note that we cannot force type name check when comparing unnamed
-    * structure types, these have a unique name assigned during parsing.
     */
-   if (!this->is_anonymous() && !b->is_anonymous())
-      if (strcmp(this->name, b->name) != 0)
-         return false;
+   if (strcmp(this->name, b->name) != 0)
+      return false;
 
    for (unsigned i = 0; i < this->length; i++) {
       if (this->fields.structure[i].type != b->fields.structure[i].type)
@@ -945,20 +958,23 @@ glsl_type::record_compare(const glsl_type *b, bool match_locations) const
       if (this->fields.structure[i].patch
           != b->fields.structure[i].patch)
          return false;
-      if (this->fields.structure[i].image_read_only
-          != b->fields.structure[i].image_read_only)
+      if (this->fields.structure[i].memory_read_only
+          != b->fields.structure[i].memory_read_only)
          return false;
-      if (this->fields.structure[i].image_write_only
-          != b->fields.structure[i].image_write_only)
+      if (this->fields.structure[i].memory_write_only
+          != b->fields.structure[i].memory_write_only)
          return false;
-      if (this->fields.structure[i].image_coherent
-          != b->fields.structure[i].image_coherent)
+      if (this->fields.structure[i].memory_coherent
+          != b->fields.structure[i].memory_coherent)
          return false;
-      if (this->fields.structure[i].image_volatile
-          != b->fields.structure[i].image_volatile)
+      if (this->fields.structure[i].memory_volatile
+          != b->fields.structure[i].memory_volatile)
          return false;
-      if (this->fields.structure[i].image_restrict
-          != b->fields.structure[i].image_restrict)
+      if (this->fields.structure[i].memory_restrict
+          != b->fields.structure[i].memory_restrict)
+         return false;
+      if (this->fields.structure[i].image_format
+          != b->fields.structure[i].image_format)
          return false;
       if (this->fields.structure[i].precision
           != b->fields.structure[i].precision)
@@ -1019,7 +1035,7 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
 {
    const glsl_type key(fields, num_fields, name);
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::hash_mutex);
 
    if (record_types == NULL) {
       record_types = _mesa_hash_table_create(NULL, record_key_hash,
@@ -1029,9 +1045,7 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
    const struct hash_entry *entry = _mesa_hash_table_search(record_types,
                                                             &key);
    if (entry == NULL) {
-      mtx_unlock(&glsl_type::mutex);
       const glsl_type *t = new glsl_type(fields, num_fields, name);
-      mtx_lock(&glsl_type::mutex);
 
       entry = _mesa_hash_table_insert(record_types, t, (void *) t);
    }
@@ -1040,7 +1054,7 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
    assert(((glsl_type *) entry->data)->length == num_fields);
    assert(strcmp(((glsl_type *) entry->data)->name, name) == 0);
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::hash_mutex);
 
    return (glsl_type *) entry->data;
 }
@@ -1055,7 +1069,7 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
 {
    const glsl_type key(fields, num_fields, packing, row_major, block_name);
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::hash_mutex);
 
    if (interface_types == NULL) {
       interface_types = _mesa_hash_table_create(NULL, record_key_hash,
@@ -1065,10 +1079,8 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
    const struct hash_entry *entry = _mesa_hash_table_search(interface_types,
                                                             &key);
    if (entry == NULL) {
-      mtx_unlock(&glsl_type::mutex);
       const glsl_type *t = new glsl_type(fields, num_fields,
                                          packing, row_major, block_name);
-      mtx_lock(&glsl_type::mutex);
 
       entry = _mesa_hash_table_insert(interface_types, t, (void *) t);
    }
@@ -1077,7 +1089,7 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
    assert(((glsl_type *) entry->data)->length == num_fields);
    assert(strcmp(((glsl_type *) entry->data)->name, block_name) == 0);
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::hash_mutex);
 
    return (glsl_type *) entry->data;
 }
@@ -1087,7 +1099,7 @@ glsl_type::get_subroutine_instance(const char *subroutine_name)
 {
    const glsl_type key(subroutine_name);
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::hash_mutex);
 
    if (subroutine_types == NULL) {
       subroutine_types = _mesa_hash_table_create(NULL, record_key_hash,
@@ -1097,9 +1109,7 @@ glsl_type::get_subroutine_instance(const char *subroutine_name)
    const struct hash_entry *entry = _mesa_hash_table_search(subroutine_types,
                                                             &key);
    if (entry == NULL) {
-      mtx_unlock(&glsl_type::mutex);
       const glsl_type *t = new glsl_type(subroutine_name);
-      mtx_lock(&glsl_type::mutex);
 
       entry = _mesa_hash_table_insert(subroutine_types, t, (void *) t);
    }
@@ -1107,7 +1117,7 @@ glsl_type::get_subroutine_instance(const char *subroutine_name)
    assert(((glsl_type *) entry->data)->base_type == GLSL_TYPE_SUBROUTINE);
    assert(strcmp(((glsl_type *) entry->data)->name, subroutine_name) == 0);
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::hash_mutex);
 
    return (glsl_type *) entry->data;
 }
@@ -1142,7 +1152,7 @@ glsl_type::get_function_instance(const glsl_type *return_type,
 {
    const glsl_type key(return_type, params, num_params);
 
-   mtx_lock(&glsl_type::mutex);
+   mtx_lock(&glsl_type::hash_mutex);
 
    if (function_types == NULL) {
       function_types = _mesa_hash_table_create(NULL, function_key_hash,
@@ -1151,9 +1161,7 @@ glsl_type::get_function_instance(const glsl_type *return_type,
 
    struct hash_entry *entry = _mesa_hash_table_search(function_types, &key);
    if (entry == NULL) {
-      mtx_unlock(&glsl_type::mutex);
       const glsl_type *t = new glsl_type(return_type, params, num_params);
-      mtx_lock(&glsl_type::mutex);
 
       entry = _mesa_hash_table_insert(function_types, t, (void *) t);
    }
@@ -1163,7 +1171,7 @@ glsl_type::get_function_instance(const glsl_type *return_type,
    assert(t->base_type == GLSL_TYPE_FUNCTION);
    assert(t->length == num_params);
 
-   mtx_unlock(&glsl_type::mutex);
+   mtx_unlock(&glsl_type::hash_mutex);
 
    return t;
 }
@@ -1298,6 +1306,8 @@ glsl_type::component_slots() const
 
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_IMAGE:
+      return 2;
+
    case GLSL_TYPE_SUBROUTINE:
       return 1;
 
@@ -1966,6 +1976,8 @@ glsl_type::count_attribute_slots(bool is_vertex_input) const
    case GLSL_TYPE_INT:
    case GLSL_TYPE_FLOAT:
    case GLSL_TYPE_BOOL:
+   case GLSL_TYPE_SAMPLER:
+   case GLSL_TYPE_IMAGE:
       return this->matrix_columns;
    case GLSL_TYPE_DOUBLE:
    case GLSL_TYPE_UINT64:
@@ -1987,12 +1999,12 @@ glsl_type::count_attribute_slots(bool is_vertex_input) const
    case GLSL_TYPE_ARRAY:
       return this->length * this->fields.array->count_attribute_slots(is_vertex_input);
 
+   case GLSL_TYPE_SUBROUTINE:
+      return 1;
+
    case GLSL_TYPE_FUNCTION:
-   case GLSL_TYPE_SAMPLER:
-   case GLSL_TYPE_IMAGE:
    case GLSL_TYPE_ATOMIC_UINT:
    case GLSL_TYPE_VOID:
-   case GLSL_TYPE_SUBROUTINE:
    case GLSL_TYPE_ERROR:
       break;
    }