Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-06-01 13:26:27 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-06-01 13:33:41 +0300
commit8c09826d58ad219b7229fcce396b967866458e99 (patch)
tree813e02d3ffda7b215f806122f80d401e809bcfbd
parent3c703df327c45f60cf4672874e700420e3a11f0d (diff)
Gawain: Optimize shader uniform access
Before this change Gawain was doing list lookup twice, doing string comparison of every and each input which is not efficient and not friendly for CPUs with small cache size. Now we store hash of input name together with actual name and compare hashes first. Additionally, we do everything in a single pass which is much better from cache coherency point of view. This brings Eevee cache population time from 80ms to 60ms on my desktop and from 800ms to 400ms for Clement when navigating in a file from T50027. Reviewers: merwin, dfelinto Subscribers: fclem Differential Revision: https://developer.blender.org/D2697
-rw-r--r--intern/gawain/gawain/shader_interface.h1
-rw-r--r--intern/gawain/src/shader_interface.c52
2 files changed, 29 insertions, 24 deletions
diff --git a/intern/gawain/gawain/shader_interface.h b/intern/gawain/gawain/shader_interface.h
index 5c37d507806..cf10180e3d5 100644
--- a/intern/gawain/gawain/shader_interface.h
+++ b/intern/gawain/gawain/shader_interface.h
@@ -32,6 +32,7 @@ typedef enum {
typedef struct {
const char* name;
+ unsigned name_hash;
GLenum gl_type;
BuiltinUniform builtin_type; // only for uniform inputs
GLint size;
diff --git a/intern/gawain/src/shader_interface.c b/intern/gawain/src/shader_interface.c
index 4a07f954c36..f0da342f088 100644
--- a/intern/gawain/src/shader_interface.c
+++ b/intern/gawain/src/shader_interface.c
@@ -49,6 +49,24 @@ static bool match(const char* a, const char* b)
return strcmp(a, b) == 0;
}
+static unsigned hash_string(const char *str)
+ {
+ unsigned i = 0, c;
+
+ while ((c = *str++))
+ {
+ i = i * 37 + c;
+ }
+
+ return i;
+ }
+
+static inline void set_input_name(ShaderInput* input, const char* name)
+ {
+ input->name = name;
+ input->name_hash = hash_string(name);
+ }
+
// keep these in sync with BuiltinUniform order
#define FIRST_MAT4_UNIFORM UNIFORM_MODELVIEW
#define LAST_MAT4_UNIFORM UNIFORM_PROJECTION_INV
@@ -67,7 +85,7 @@ static bool setup_builtin_uniform(ShaderInput* input, const char* name)
const char* builtin_name = BuiltinUniform_name(u);
if (match(name, builtin_name))
{
- input->name = builtin_name;
+ set_input_name(input, builtin_name);
input->builtin_type = u;
return true;
}
@@ -78,7 +96,7 @@ static bool setup_builtin_uniform(ShaderInput* input, const char* name)
const char* builtin_name = BuiltinUniform_name(UNIFORM_NORMAL);
if (match(name, builtin_name))
{
- input->name = builtin_name;
+ set_input_name(input, builtin_name);
input->builtin_type = UNIFORM_NORMAL;
return true;
}
@@ -89,7 +107,7 @@ static bool setup_builtin_uniform(ShaderInput* input, const char* name)
const char* builtin_name = BuiltinUniform_name(UNIFORM_COLOR);
if (match(name, builtin_name))
{
- input->name = builtin_name;
+ set_input_name(input, builtin_name);
input->builtin_type = UNIFORM_COLOR;
return true;
}
@@ -149,7 +167,7 @@ ShaderInterface* ShaderInterface_create(GLint program)
; // reclaim space from name buffer (don't advance offset)
else
{
- input->name = name;
+ set_input_name(input, name);
name_buffer_offset += name_len + 1; // include NULL terminator
}
#if SUPPORT_LEGACY_GLSL
@@ -181,7 +199,7 @@ ShaderInterface* ShaderInterface_create(GLint program)
assert(input->location != -1);
#endif
- input->name = name;
+ set_input_name(input, name);
name_buffer_offset += name_len + 1; // include NULL terminator
#if SUPPORT_LEGACY_GLSL
}
@@ -233,33 +251,19 @@ void ShaderInterface_discard(ShaderInterface* shaderface)
const ShaderInput* ShaderInterface_uniform(const ShaderInterface* shaderface, const char* name)
{
- // search through custom uniforms first
+ const unsigned name_hash = hash_string(name);
for (uint32_t i = 0; i < shaderface->uniform_ct; ++i)
{
const ShaderInput* uniform = shaderface->inputs + i;
- if (uniform->builtin_type == UNIFORM_CUSTOM)
- {
#if SUPPORT_LEGACY_GLSL
- if (uniform->name == NULL) continue;
+ if (uniform->name == NULL) continue;
#endif
- if (match(uniform->name, name))
- return uniform;
- }
- }
+ if (uniform->name_hash != name_hash) continue;
- // search through builtin uniforms next
- for (uint32_t i = 0; i < shaderface->uniform_ct; ++i)
- {
- const ShaderInput* uniform = shaderface->inputs + i;
-
-#if SUPPORT_LEGACY_GLSL
- if (uniform->name == NULL) continue;
-#endif
- if (uniform->builtin_type != UNIFORM_CUSTOM)
- if (match(uniform->name, name))
- return uniform;
+ if (match(uniform->name, name))
+ return uniform;
// TODO: warn if we find a matching builtin, since these can be looked up much quicker --v
}