diff options
author | Marek Olšák <marek.olsak@amd.com> | 2021-10-23 19:39:12 -0400 |
---|---|---|
committer | Marek Olšák <marek.olsak@amd.com> | 2021-10-29 07:19:20 -0400 |
commit | 7fe3cc94ebed922e87aa0ac329abe52166111286 (patch) | |
tree | 7e14fe66677f50eb194529e5c61bd6874bf41994 /src/mesa/main | |
parent | 1b1425d45c6be1f911c7da222a2326814409ff7e (diff) |
mesa: add separate hash tables for each GLSL resource type
This removes the malloc for the key, the associated string pointer
indirection, and hopefully the hash table has fewer elements than
the global one.
This decrease overhead of glGetUniformLocation.
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13507>
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/mtypes.h | 8 | ||||
-rw-r--r-- | src/mesa/main/shader_query.cpp | 75 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.h | 2 | ||||
-rw-r--r-- | src/mesa/main/shaderobj.c | 7 |
4 files changed, 39 insertions, 53 deletions
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)); + + 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, - key, res); + _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); } |