diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-10-05 16:38:23 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-10-05 16:38:23 +0300 |
commit | 5514d2df1c6d9f2f108336e46b0db14316610d24 (patch) | |
tree | 0572f1e788420650f2fd33fe479b79dd127160ed /intern/gawain | |
parent | e1e452c0629ee74b527439b64681396c71afe4e1 (diff) |
Gawain: Optimize out extra level on top of ShaderInput
This is an internal structure, and we don't put it to a list for anything else
that hash collision resolution. No need to have dedicated entry here, saves us
from extra allocation and pointer dereference.
Diffstat (limited to 'intern/gawain')
-rw-r--r-- | intern/gawain/gawain/gwn_shader_interface.h | 10 | ||||
-rw-r--r-- | intern/gawain/src/gwn_shader_interface.c | 45 |
2 files changed, 16 insertions, 39 deletions
diff --git a/intern/gawain/gawain/gwn_shader_interface.h b/intern/gawain/gawain/gwn_shader_interface.h index 4c3d44cadbd..b2d48e3c301 100644 --- a/intern/gawain/gawain/gwn_shader_interface.h +++ b/intern/gawain/gawain/gwn_shader_interface.h @@ -33,6 +33,7 @@ typedef enum { } Gwn_UniformBuiltin; typedef struct Gwn_ShaderInput { + struct Gwn_ShaderInput* next; const char* name; unsigned name_hash; GLenum gl_type; @@ -41,18 +42,13 @@ typedef struct Gwn_ShaderInput { GLint location; } Gwn_ShaderInput; -typedef struct Gwn_ShaderInput_Entry { - struct Gwn_ShaderInput_Entry* next; - Gwn_ShaderInput* shader_input; -} Gwn_ShaderInput_Entry; - #define GWN_NUM_SHADERINTERFACE_BUCKETS 1009 typedef struct Gwn_ShaderInterface { uint16_t uniform_ct; uint16_t attrib_ct; - Gwn_ShaderInput_Entry* uniform_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; - Gwn_ShaderInput_Entry* attrib_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; + Gwn_ShaderInput* uniform_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; + Gwn_ShaderInput* attrib_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; Gwn_ShaderInput* builtin_uniforms[GWN_NUM_UNIFORMS]; Gwn_ShaderInput inputs[0]; // dynamic size, uniforms followed by attribs } Gwn_ShaderInterface; diff --git a/intern/gawain/src/gwn_shader_interface.c b/intern/gawain/src/gwn_shader_interface.c index 5305dae9a9a..247e95e113a 100644 --- a/intern/gawain/src/gwn_shader_interface.c +++ b/intern/gawain/src/gwn_shader_interface.c @@ -69,22 +69,20 @@ GWN_INLINE void set_input_name(Gwn_ShaderInput* input, const char* name) } GWN_INLINE void shader_input_to_bucket(Gwn_ShaderInput* input, - Gwn_ShaderInput_Entry* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) + Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) { - Gwn_ShaderInput_Entry* entry = malloc(sizeof(Gwn_ShaderInput_Entry)); const unsigned bucket_index = input->name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; - entry->next = buckets[bucket_index]; - entry->shader_input = input; - buckets[bucket_index] = entry; + input->next = buckets[bucket_index]; + buckets[bucket_index] = input; } -GWN_INLINE Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput_Entry* const buckets[GWN_NUM_SHADERINTERFACE_BUCKETS], +GWN_INLINE Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[GWN_NUM_SHADERINTERFACE_BUCKETS], const char *name) { const unsigned name_hash = hash_string(name); const unsigned bucket_index = name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; - const Gwn_ShaderInput_Entry* entry = buckets[bucket_index]; - if (entry == NULL) + Gwn_ShaderInput* input = buckets[bucket_index]; + if (input == NULL) { // Requested uniform is not found at all. return NULL; @@ -92,22 +90,22 @@ GWN_INLINE Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput_Entry* const buckets[ // Optimization bit: if there is no hash collision detected when constructing shader interface // it means we can only request the single possible uniform. Surely, it's possible we request // uniform which causes hash collision, but that will be detected in debug builds. - if (entry->next == NULL) + if (input->next == NULL) { - if (name_hash == entry->shader_input->name_hash) + if (name_hash == input->name_hash) { #if TRUST_NO_ONE - assert(match(entry->shader_input->name, name)); + assert(match(input->name, name)); #endif - return entry->shader_input; + return input; } return NULL; } // Work through possible collisions. - while (entry != NULL) + while (input != NULL) { - Gwn_ShaderInput* uniform = entry->shader_input; - entry = entry->next; + Gwn_ShaderInput* uniform = input; + input = input->next; #if SUPPORT_LEGACY_GLSL if (uniform->name == NULL) continue; #endif @@ -123,20 +121,6 @@ GWN_INLINE Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput_Entry* const buckets[ return NULL; // not found } -GWN_INLINE void buckets_free(Gwn_ShaderInput_Entry* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) - { - for (unsigned bucket_index = 0; bucket_index < GWN_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) - { - Gwn_ShaderInput_Entry *entry = buckets[bucket_index]; - while (entry != NULL) - { - Gwn_ShaderInput_Entry *entry_next = entry->next; - free(entry); - entry = entry_next; - } - } - } - // keep these in sync with Gwn_UniformBuiltin order #define FIRST_MAT4_UNIFORM GWN_UNIFORM_MODELVIEW #define LAST_MAT4_UNIFORM GWN_UNIFORM_PROJECTION_INV @@ -332,9 +316,6 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(GLint program) void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface) { - // Free memory used by buckets and has entries. - buckets_free(shaderface->uniform_buckets); - buckets_free(shaderface->attrib_buckets); // Free memory used by shader interface by its self. free(shaderface); } |