glsl_type: Add get_record_instance method
This commit is contained in:
@@ -2383,7 +2383,6 @@ ir_rvalue *
|
||||
ast_struct_specifier::hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
void *ctx = talloc_parent(state);
|
||||
unsigned decl_count = 0;
|
||||
|
||||
/* Make an initial pass over the list of structure fields to determine how
|
||||
@@ -2446,7 +2445,8 @@ ast_struct_specifier::hir(exec_list *instructions,
|
||||
name = this->name;
|
||||
}
|
||||
|
||||
glsl_type *t = new(ctx) glsl_type(fields, decl_count, name);
|
||||
const glsl_type *t =
|
||||
glsl_type::get_record_instance(fields, decl_count, name);
|
||||
|
||||
YYLTYPE loc = this->get_location();
|
||||
if (!state->symbols->add_type(name, t)) {
|
||||
|
@@ -32,6 +32,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
hash_table *glsl_type::array_types = NULL;
|
||||
hash_table *glsl_type::record_types = NULL;
|
||||
|
||||
glsl_type::glsl_type(GLenum gl_type,
|
||||
unsigned base_type, unsigned vector_elements,
|
||||
@@ -384,6 +385,77 @@ glsl_type::get_array_instance(void *ctx, const glsl_type *base,
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
if (strcmp(key1->name, key2->name) != 0)
|
||||
return 1;
|
||||
|
||||
if (key1->length != key2->length)
|
||||
return 1;
|
||||
|
||||
for (unsigned i = 0; i < key1->length; i++)
|
||||
/* FINISHME: Is the name of the structure field also significant? */
|
||||
if (key1->fields.structure[i].type != key2->fields.structure[i].type)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
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);
|
||||
|
||||
for (unsigned i = 0; i < key->length; i++) {
|
||||
if (size >= sizeof(hash_key))
|
||||
break;
|
||||
|
||||
size += snprintf(& hash_key[size], sizeof(hash_key) - size,
|
||||
"%p", key->fields.structure[i].type);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (t == NULL) {
|
||||
t = new(NULL) glsl_type(fields, num_fields, name);
|
||||
|
||||
hash_table_insert(record_types, (void *) t, t);
|
||||
}
|
||||
|
||||
assert(t->base_type == GLSL_TYPE_STRUCT);
|
||||
assert(t->length == num_fields);
|
||||
assert(strcmp(t->name, name) == 0);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
const glsl_type *
|
||||
glsl_type::field_type(const char *name) const
|
||||
{
|
||||
|
@@ -205,6 +205,12 @@ struct glsl_type {
|
||||
const glsl_type *base,
|
||||
unsigned elements);
|
||||
|
||||
/**
|
||||
* Get the instance of a record type
|
||||
*/
|
||||
static const glsl_type *get_record_instance(const glsl_struct_field *fields,
|
||||
unsigned num_fields,
|
||||
const char *name);
|
||||
/**
|
||||
* Generate the constructor for this type and add it to the symbol table
|
||||
*/
|
||||
@@ -407,6 +413,12 @@ private:
|
||||
static int array_key_compare(const void *a, const void *b);
|
||||
static unsigned array_key_hash(const void *key);
|
||||
|
||||
/** Hash table containing the known record types. */
|
||||
static struct hash_table *record_types;
|
||||
|
||||
static int record_key_compare(const void *a, const void *b);
|
||||
static unsigned record_key_hash(const void *key);
|
||||
|
||||
/**
|
||||
* \name Pointers to various type singletons
|
||||
*/
|
||||
|
Reference in New Issue
Block a user