diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 9a0cf022e5b..9b2eb8afb12 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2954,6 +2954,12 @@ enum gl_link_status LINKING_SKIPPED }; +/* All GLSL program resource types are next to each other, so we can use that + * to make them 0-based like this: + */ +#define GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(x) ((x) - GL_UNIFORM) +#define NUM_PROGRAM_RESOURCE_TYPES (GL_TRANSFORM_FEEDBACK_VARYING - GL_UNIFORM + 1) + /** * A data structure to be shared by gl_shader_program and gl_program. */ @@ -2993,7 +2999,7 @@ struct gl_shader_program_data union gl_constant_value *UniformDataDefaults; /** Hash for quick search by name. */ - struct hash_table *ProgramResourceHash; + struct hash_table *ProgramResourceHash[NUM_PROGRAM_RESOURCE_TYPES]; GLboolean Validated; diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 3b4ea7753da..4ecb4f40938 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -39,11 +39,6 @@ #include "compiler/glsl/string_to_uint_map.h" #include "util/mesa-sha1.h" -struct program_resource_key { - const char *name; - GLenum type; -}; - static GLint program_resource_location(struct gl_program_resource *res, unsigned array_index); @@ -637,6 +632,12 @@ search_resource_hash(struct gl_shader_program *shProg, GLenum programInterface, const char *name, int len, unsigned *array_index) { + unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(programInterface); + assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash)); + + if (!shProg->data->ProgramResourceHash[type]) + return NULL; + const char *base_name_end; long index = parse_program_resource_name(name, len, &base_name_end); char *name_copy; @@ -651,12 +652,10 @@ search_resource_hash(struct gl_shader_program *shProg, name_copy = (char*) name; } - struct program_resource_key key; - key.name = name_copy; - key.type = programInterface; - + uint32_t hash = _mesa_hash_string(name_copy); struct hash_entry *entry = - _mesa_hash_table_search(shProg->data->ProgramResourceHash, &key); + _mesa_hash_table_search_pre_hashed(shProg->data->ProgramResourceHash[type], + hash, name_copy); if (!entry) return NULL; @@ -673,16 +672,14 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, GLenum programInterface, const char *name, unsigned *array_index) { - struct gl_program_resource *res = NULL; - if (name == NULL) return NULL; int len = strlen(name); /* If we have a name, try the ProgramResourceHash first. */ - if (shProg->data->ProgramResourceHash) - res = search_resource_hash(shProg, programInterface, name, len, array_index); + struct gl_program_resource *res = + search_resource_hash(shProg, programInterface, name, len, array_index); if (res) return res; @@ -2006,52 +2003,38 @@ _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline) return true; } -static uint32_t -hash_resource_key(const void *_key) -{ - struct program_resource_key *key = (struct program_resource_key *)_key; - - return _mesa_hash_data_with_seed(key->name, strlen(key->name), key->type); -} - -static bool -resource_key_equal(const void *a, const void *b) -{ - struct program_resource_key *keya = (struct program_resource_key *)a; - struct program_resource_key *keyb = (struct program_resource_key *)b; - - return keya->type == keyb->type && strcmp(keya->name, keyb->name) == 0; -} - extern "C" void -_mesa_program_resource_key_delete(struct hash_entry *entry) +_mesa_program_resource_hash_destroy(struct gl_shader_program *shProg) { - free((void*)entry->key); + for (unsigned i = 0; i < ARRAY_SIZE(shProg->data->ProgramResourceHash); i++) { + if (shProg->data->ProgramResourceHash[i]) { + _mesa_hash_table_destroy(shProg->data->ProgramResourceHash[i], NULL); + shProg->data->ProgramResourceHash[i] = NULL; + } + } } extern "C" void _mesa_create_program_resource_hash(struct gl_shader_program *shProg) { /* Rebuild resource hash. */ - if (shProg->data->ProgramResourceHash) - _mesa_hash_table_destroy(shProg->data->ProgramResourceHash, - _mesa_program_resource_key_delete); - - shProg->data->ProgramResourceHash = - _mesa_hash_table_create(shProg, hash_resource_key, - resource_key_equal); + _mesa_program_resource_hash_destroy(shProg); struct gl_program_resource *res = shProg->data->ProgramResourceList; for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { struct gl_resource_name name; if (_mesa_program_get_resource_name(res, &name)) { - struct program_resource_key *key = - (struct program_resource_key *)malloc(sizeof(*key)); - key->name = name.string; - key->type = res->Type; + unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(res->Type); + assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash)); - _mesa_hash_table_insert(shProg->data->ProgramResourceHash, - key, res); + if (!shProg->data->ProgramResourceHash[type]) { + shProg->data->ProgramResourceHash[type] = + _mesa_hash_table_create(shProg, _mesa_hash_string, + _mesa_key_string_equal); + } + + _mesa_hash_table_insert(shProg->data->ProgramResourceHash[type], + name.string, res); } } } diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index f826ce6e4fe..0e101866661 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -342,7 +342,7 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg, GLint *params); extern void -_mesa_program_resource_key_delete(struct hash_entry *entry); +_mesa_program_resource_hash_destroy(struct gl_shader_program *shProg); extern void _mesa_create_program_resource_hash(struct gl_shader_program *shProg); diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 74b6a27fada..9fadece8424 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -357,11 +357,8 @@ _mesa_clear_shader_program_data(struct gl_context *ctx, shProg->UniformHash = NULL; } - if (shProg->data && shProg->data->ProgramResourceHash) { - _mesa_hash_table_destroy(shProg->data->ProgramResourceHash, - _mesa_program_resource_key_delete); - shProg->data->ProgramResourceHash = NULL; - } + if (shProg->data) + _mesa_program_resource_hash_destroy(shProg); _mesa_reference_shader_program_data(ctx, &shProg->data, NULL); }