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.roman...@intel.com> Signed-off-by: Chad Versace <c...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev