summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2020-01-03 07:56:23 +0200
committerMarge Bot <eric+marge@anholt.net>2020-01-07 10:48:41 +0000
commitdd09f1d806bab62e2399d2fc7a5d0922c594eab3 (patch)
tree7958b8eec9f359fefc6b31e4deb1f7a6539fe2b8
parent5f0ff004ca8f0e59270f0ea4dc8f13c74ce88e2b (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 <tapani.palli@intel.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3254> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3254>
-rw-r--r--src/mesa/drivers/dri/i965/brw_link.cpp2
-rw-r--r--src/mesa/main/mtypes.h3
-rw-r--r--src/mesa/main/shader_query.cpp83
-rw-r--r--src/mesa/main/shaderapi.h3
-rw-r--r--src/mesa/main/shaderobj.c5
-rw-r--r--src/mesa/state_tracker/st_glsl_to_nir.cpp2
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp2
7 files changed, 95 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp b/src/mesa/drivers/dri/i965/brw_link.cpp
index 2a844575c3d..8a62ffd760b 100644
--- a/src/mesa/drivers/dri/i965/brw_link.cpp
+++ b/src/mesa/drivers/dri/i965/brw_link.cpp
@@ -388,6 +388,8 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
else
nir_build_program_resource_list(ctx, shProg, true);
+ _mesa_create_program_resource_hash(shProg);
+
for (stage = 0; stage < ARRAY_SIZE(shProg->_LinkedShaders); stage++) {
struct gl_linked_shader *shader = shProg->_LinkedShaders[stage];
if (!shader)
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);
}
diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp
index c92b1c365a7..b01cc3fd8d9 100644
--- a/src/mesa/state_tracker/st_glsl_to_nir.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp
@@ -843,6 +843,8 @@ st_link_nir(struct gl_context *ctx,
prev_info = info;
}
+ _mesa_create_program_resource_hash(shader_program);
+
return true;
}
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index b6c2c2deb77..cd77effebc4 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -7428,5 +7428,7 @@ st_link_tgsi(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
+ _mesa_create_program_resource_hash(prog);
+
return GL_TRUE;
}