Commit: 8c09826d58ad219b7229fcce396b967866458e99
Author: Sergey Sharybin
Date:   Thu Jun 1 12:26:27 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB8c09826d58ad219b7229fcce396b967866458e99

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

===================================================================

M       intern/gawain/gawain/shader_interface.h
M       intern/gawain/src/shader_interface.c

===================================================================

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
                }

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to