summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2021-10-23 19:39:12 -0400
committerMarek Olšák <marek.olsak@amd.com>2021-10-29 07:19:20 -0400
commit7fe3cc94ebed922e87aa0ac329abe52166111286 (patch)
tree7e14fe66677f50eb194529e5c61bd6874bf41994 /src/mesa/main
parent1b1425d45c6be1f911c7da222a2326814409ff7e (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.h8
-rw-r--r--src/mesa/main/shader_query.cpp75
-rw-r--r--src/mesa/main/shaderapi.h2
-rw-r--r--src/mesa/main/shaderobj.c7
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);
}