[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