diff options
author | Tapani Pälli <[email protected]> | 2020-01-03 07:56:23 +0200 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-01-07 10:48:41 +0000 |
commit | dd09f1d806bab62e2399d2fc7a5d0922c594eab3 (patch) | |
tree | 7958b8eec9f359fefc6b31e4deb1f7a6539fe2b8 /src/mesa/main | |
parent | 5f0ff004ca8f0e59270f0ea4dc8f13c74ce88e2b (diff) |
mesa/st/i965: add a ProgramResourceHash for quicker resource lookup
Many resource APIs require searching by name, add a hash table to make
this faster. Currently we traverse the whole resource list for name
based queries, this change makes all these cases use the hash.
Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/2203
Signed-off-by: Tapani Pälli <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3254>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3254>
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/mtypes.h | 3 | ||||
-rw-r--r-- | src/mesa/main/shader_query.cpp | 83 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.h | 3 | ||||
-rw-r--r-- | src/mesa/main/shaderobj.c | 5 |
4 files changed, 89 insertions, 5 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 3b3e7ddb8de..02766d3aced 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2917,6 +2917,9 @@ struct gl_shader_program_data */ union gl_constant_value *UniformDataDefaults; + /** Hash for quick search by name. */ + struct hash_table_u64 *ProgramResourceHash; + GLboolean Validated; /** List of all active resources after linking. */ diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 000e2a16ea7..1a50abc31d0 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -37,7 +37,7 @@ #include "compiler/glsl/ir.h" #include "compiler/glsl/program.h" #include "compiler/glsl/string_to_uint_map.h" - +#include "util/mesa-sha1.h" static GLint program_resource_location(struct gl_program_resource *res, @@ -461,7 +461,7 @@ _mesa_program_resource_name(struct gl_program_resource *res) case GL_TESS_EVALUATION_SUBROUTINE: return RESOURCE_SUB(res)->name; default: - assert(!"support for resource type not implemented"); + break; } return NULL; } @@ -527,6 +527,51 @@ valid_array_index(const GLchar *name, unsigned *array_index) return true; } +static uint32_t +compute_resource_key(GLenum programInterface, const char *name) +{ + struct mesa_sha1 ctx; + unsigned char sha1[20]; + + _mesa_sha1_init(&ctx); + _mesa_sha1_update(&ctx, &programInterface, sizeof(programInterface)); + _mesa_sha1_update(&ctx, name, strlen(name)); + _mesa_sha1_final(&ctx, sha1); + + return _mesa_hash_data(sha1, sizeof(sha1)); +} + +static struct gl_program_resource * +search_resource_hash(struct gl_shader_program *shProg, + GLenum programInterface, const char *name, + unsigned *array_index) +{ + const char *base_name_end; + long index = parse_program_resource_name(name, &base_name_end); + char *name_copy; + + /* If dealing with array, we need to get the basename. */ + if (index >= 0) { + name_copy = (char *) malloc(base_name_end - name + 1); + memcpy(name_copy, name, base_name_end - name); + name_copy[base_name_end - name] = '\0'; + } else { + name_copy = (char*) name; + } + + uint32_t key = compute_resource_key(programInterface, name_copy); + struct gl_program_resource *res = (struct gl_program_resource *) + _mesa_hash_table_u64_search(shProg->data->ProgramResourceHash, key); + + if (name_copy != name) + free(name_copy); + + if (res && array_index) + *array_index = index >= 0 ? index : 0; + + return res; +} + /* Find a program resource with specific name in given interface. */ struct gl_program_resource * @@ -534,9 +579,17 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, GLenum programInterface, const char *name, unsigned *array_index) { - struct gl_program_resource *res = shProg->data->ProgramResourceList; - for (unsigned i = 0; i < shProg->data->NumProgramResourceList; - i++, res++) { + struct gl_program_resource *res = NULL; + + /* If we have a name, try the ProgramResourceHash first. */ + if (name && shProg->data->ProgramResourceHash) + res = search_resource_hash(shProg, programInterface, name, array_index); + + if (res) + return res; + + res = shProg->data->ProgramResourceList; + for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { if (res->Type != programInterface) continue; @@ -1850,3 +1903,23 @@ _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline) } return true; } + +extern "C" void +_mesa_create_program_resource_hash(struct gl_shader_program *shProg) +{ + /* Rebuild resource hash. */ + if (shProg->data->ProgramResourceHash) + _mesa_hash_table_u64_destroy(shProg->data->ProgramResourceHash, NULL); + + shProg->data->ProgramResourceHash = _mesa_hash_table_u64_create(shProg); + + struct gl_program_resource *res = shProg->data->ProgramResourceList; + for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { + const char *name = _mesa_program_resource_name(res); + if (name) { + uint32_t key = compute_resource_key(res->Type, name); + _mesa_hash_table_u64_insert(shProg->data->ProgramResourceHash, key, + res); + } + } +} diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index 66acb6a9694..bba737868ef 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -332,6 +332,9 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg, GLsizei bufSize, GLsizei *length, GLint *params); +extern void +_mesa_create_program_resource_hash(struct gl_shader_program *shProg); + /* GL_ARB_tessellation_shader */ void GLAPIENTRY _mesa_PatchParameteri_no_error(GLenum pname, GLint value); diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 834e2a92ec4..a2478d96975 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -344,6 +344,11 @@ _mesa_clear_shader_program_data(struct gl_context *ctx, shProg->UniformHash = NULL; } + if (shProg->data && shProg->data->ProgramResourceHash) { + _mesa_hash_table_u64_destroy(shProg->data->ProgramResourceHash, NULL); + shProg->data->ProgramResourceHash = NULL; + } + _mesa_reference_shader_program_data(ctx, &shProg->data, NULL); } |