X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=inline;f=src%2Fglsl%2Fglsl_types.cpp;h=82eb470605689761b387e8c4f1a18963a7e5875f;hb=3cdff41d9245f997c465869148a74a2041739504;hp=158659c71e5d0557cca73afb1ba68d2b8323b41f;hpb=31bcce04b1f9c8c5e33370e26a3a9d6e60049aa8;p=mesa.git diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 158659c71e5..82eb4706056 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -23,15 +23,27 @@ #include #include +#include "main/core.h" /* for Elements */ #include "glsl_symbol_table.h" #include "glsl_parser_extras.h" #include "glsl_types.h" #include "builtin_types.h" extern "C" { -#include "hash_table.h" +#include "program/hash_table.h" } hash_table *glsl_type::array_types = NULL; +hash_table *glsl_type::record_types = NULL; +void *glsl_type::mem_ctx = NULL; + +void +glsl_type::init_talloc_type_ctx(void) +{ + if (glsl_type::mem_ctx == NULL) { + glsl_type::mem_ctx = talloc_autofree_context(); + assert(glsl_type::mem_ctx != NULL); + } +} glsl_type::glsl_type(GLenum gl_type, unsigned base_type, unsigned vector_elements, @@ -41,9 +53,10 @@ glsl_type::glsl_type(GLenum gl_type, sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), sampler_type(0), vector_elements(vector_elements), matrix_columns(matrix_columns), - name(name), length(0) { + init_talloc_type_ctx(); + this->name = talloc_strdup(this->mem_ctx, name); /* Neither dimension is zero or both dimensions are zero. */ assert((vector_elements == 0) == (matrix_columns == 0)); @@ -58,12 +71,34 @@ glsl_type::glsl_type(GLenum gl_type, sampler_dimensionality(dim), sampler_shadow(shadow), sampler_array(array), sampler_type(type), vector_elements(0), matrix_columns(0), - name(name), length(0) { + init_talloc_type_ctx(); + this->name = talloc_strdup(this->mem_ctx, name); 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) +{ + unsigned int i; + + init_talloc_type_ctx(); + this->name = talloc_strdup(this->mem_ctx, name); + this->fields.structure = talloc_array(this->mem_ctx, + glsl_struct_field, length); + for (i = 0; i < length; i++) { + this->fields.structure[i].type = fields[i].type; + this->fields.structure[i].name = talloc_strdup(this->fields.structure, + fields[i].name); + } +} + static void add_types_to_symbol_table(glsl_symbol_table *symtab, const struct glsl_type *types, @@ -76,9 +111,8 @@ add_types_to_symbol_table(glsl_symbol_table *symtab, } } - void -glsl_type::generate_110_types(glsl_symbol_table *symtab) +glsl_type::generate_100ES_types(glsl_symbol_table *symtab) { add_types_to_symbol_table(symtab, builtin_core_types, Elements(builtin_core_types), @@ -86,10 +120,20 @@ glsl_type::generate_110_types(glsl_symbol_table *symtab) add_types_to_symbol_table(symtab, builtin_structure_types, 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) +{ + generate_100ES_types(symtab); + + add_types_to_symbol_table(symtab, builtin_110_types, + Elements(builtin_110_types), + false); add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types, Elements(builtin_110_deprecated_structure_types), false); - add_types_to_symbol_table(symtab, & void_type, 1, false); } @@ -110,6 +154,7 @@ glsl_type::generate_130_types(glsl_symbol_table *symtab) add_types_to_symbol_table(symtab, builtin_130_types, Elements(builtin_130_types), false); + generate_EXT_texture_array_types(symtab, false); } @@ -137,6 +182,10 @@ void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) { switch (state->language_version) { + case 100: + assert(state->es_shader); + glsl_type::generate_100ES_types(state->symbols); + break; case 110: glsl_type::generate_110_types(state->symbols); break; @@ -181,69 +230,22 @@ const glsl_type *glsl_type::get_base_type() const } -ir_function * -glsl_type::generate_constructor(glsl_symbol_table *symtab) const +void +_mesa_glsl_release_types(void) { - void *ctx = symtab; - - /* Generate the function name and add it to the symbol table. - */ - ir_function *const f = new(ctx) ir_function(name); - - bool added = symtab->add_function(name, f); - assert(added); - - ir_function_signature *const sig = new(ctx) ir_function_signature(this); - f->add_signature(sig); - - ir_variable **declarations = - (ir_variable **) malloc(sizeof(ir_variable *) * this->length); - for (unsigned i = 0; i < length; i++) { - char *const param_name = (char *) malloc(10); - - snprintf(param_name, 10, "p%08X", i); - - ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY) - ? new(ctx) ir_variable(fields.array, param_name) - : new(ctx) ir_variable(fields.structure[i].type, param_name); - - var->mode = ir_var_in; - declarations[i] = var; - sig->parameters.push_tail(var); + if (glsl_type::array_types != NULL) { + hash_table_dtor(glsl_type::array_types); + glsl_type::array_types = NULL; } - /* Generate the body of the constructor. The body assigns each of the - * parameters to a portion of a local variable called __retval that has - * the same type as the constructor. After initializing __retval, - * __retval is returned. - */ - ir_variable *retval = new(ctx) ir_variable(this, "__retval"); - sig->body.push_tail(retval); - - for (unsigned i = 0; i < length; i++) { - ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY) - ? (ir_dereference *) new(ctx) ir_dereference_array(retval, - new(ctx) ir_constant(i)) - : (ir_dereference *) new(ctx) ir_dereference_record(retval, - fields.structure[i].name); - - ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]); - ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL); - - sig->body.push_tail(assign); + if (glsl_type::record_types != NULL) { + hash_table_dtor(glsl_type::record_types); + glsl_type::record_types = NULL; } - - free(declarations); - - ir_dereference *const retref = new(ctx) ir_dereference_variable(retval); - ir_instruction *const inst = new(ctx) ir_return(retref); - sig->body.push_tail(inst); - - return f; } -glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) : +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), @@ -251,13 +253,18 @@ glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) : 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 + * is represented by the size rather than the type. + */ + this->gl_type = array->gl_type; /* Allow a maximum of 10 characters for the array size. This is enough * for 32-bits of ~0. The extra 3 are for the '[', ']', and terminating * NUL. */ const unsigned name_length = strlen(array->name) + 10 + 3; - char *const n = (char *) talloc_size(ctx, name_length); + char *const n = (char *) talloc_size(this->mem_ctx, name_length); if (length == 0) snprintf(n, name_length, "%s[]", array->name); @@ -326,8 +333,40 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) } +const glsl_type * +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); + } + + /* Generate a name using the base type pointer in the key. This is + * done because the name of the base type may not be unique across + * shaders. For example, two shaders may have different record types + * named 'foo'. + */ + char key[128]; + snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size); + + const glsl_type *t = (glsl_type *) hash_table_find(array_types, key); + if (t == NULL) { + t = new glsl_type(base, array_size); + + hash_table_insert(array_types, (void *) t, talloc_strdup(mem_ctx, key)); + } + + assert(t->base_type == GLSL_TYPE_ARRAY); + assert(t->length == array_size); + assert(t->fields.array == base); + + return t; +} + + int -glsl_type::array_key_compare(const void *a, const void *b) +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; @@ -335,50 +374,66 @@ glsl_type::array_key_compare(const void *a, const void *b) /* Return zero is the types match (there is zero difference) or non-zero * otherwise. */ - return ((key1->fields.array == key2->fields.array) - && (key1->length == key2->length)) ? 0 : 1; + if (strcmp(key1->name, key2->name) != 0) + return 1; + + if (key1->length != key2->length) + return 1; + + 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) + return 1; + } + + return 0; } unsigned -glsl_type::array_key_hash(const void *a) +glsl_type::record_key_hash(const void *a) { const glsl_type *const key = (glsl_type *) a; + char hash_key[128]; + unsigned size = 0; + + size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length); - const struct { - const glsl_type *t; - unsigned l; - char nul; - } hash_key = { - key->fields.array, - key->length, - '\0' - }; + for (unsigned i = 0; i < key->length; i++) { + if (size >= sizeof(hash_key)) + break; + + size += snprintf(& hash_key[size], sizeof(hash_key) - size, + "%p", (void *) key->fields.structure[i].type); + } return hash_table_string_hash(& hash_key); } const glsl_type * -glsl_type::get_array_instance(void *ctx, const glsl_type *base, - unsigned array_size) +glsl_type::get_record_instance(const glsl_struct_field *fields, + unsigned num_fields, + const char *name) { - const glsl_type key(ctx, base, array_size); + const glsl_type key(fields, num_fields, name); - if (array_types == NULL) { - array_types = hash_table_ctor(64, array_key_hash, array_key_compare); + 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(array_types, & key); + const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key); if (t == NULL) { - t = new(ctx) glsl_type(ctx, base, array_size); + t = new glsl_type(fields, num_fields, name); - hash_table_insert(array_types, (void *) t, t); + hash_table_insert(record_types, (void *) t, t); } - assert(t->base_type == GLSL_TYPE_ARRAY); - assert(t->length == array_size); - assert(t->fields.array == base); + assert(t->base_type == GLSL_TYPE_STRUCT); + assert(t->length == num_fields); + assert(strcmp(t->name, name) == 0); return t; }