From f494baf976c4494dd0ea4e755907cf49b026eb5d Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 1 Nov 2025 14:22:34 -0700 Subject: Better hashing of shaders --- src/core/core.c | 36 ++++++++++++++++++++---------------- src/core/core_impl.h | 8 +++++--- 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/core/core.c b/src/core/core.c index e1671ea..9c04cc7 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -3,6 +3,7 @@ #include "gl_util.h" // #include +#include #include @@ -282,26 +283,29 @@ void gfx_destroy_framebuffer(GfxCore* gfxcore, FrameBuffer** framebuffer) { // Shaders. // ----------------------------------------------------------------------------- -static uint64_t hash_shader_desc(const ShaderDesc* desc) { +static hash_t hash_shader_desc(const ShaderDesc* desc) { assert(desc); - // Note that defines may affect shader permutations, so we need to hash those - // as well. - uint64_t hash = 0; + // Defines may affect shader permutations, so we need to hash those as well. + hash_t hash = fnv1a32_begin(); + hash = fnv1a32_update(hash, desc->code, strlen(desc->code)); for (size_t i = 0; i < desc->num_defines; ++i) { const ShaderCompilerDefine* define = &desc->defines[i]; - hash = (((hash << 13) + sstring_hash(define->name)) << 7) + - sstring_hash(define->value); + + hash = fnv1a32_update( + hash, sstring_cstr(&define->name), sstring_length(&define->name)); + hash = fnv1a32_update( + hash, sstring_cstr(&define->value), sstring_length(&define->value)); } - return (hash << 17) + cstring_hash(desc->code); + return hash; } -static uint64_t hash_program_desc(const ShaderProgramDesc* desc) { +static hash_t hash_program_desc(const ShaderProgramDesc* desc) { assert(desc); - return ((uint64_t)desc->vertex_shader->id << 32) | - (uint64_t)desc->fragment_shader->id; + return ((hash_t)desc->vertex_shader->id << 16) | + (hash_t)desc->fragment_shader->id; } -static Shader* find_cached_shader(ShaderCache* cache, uint64_t hash) { +static Shader* find_cached_shader(ShaderCache* cache, hash_t hash) { assert(cache); mempool_foreach(cache, entry, { if (entry->hash == hash) { @@ -311,7 +315,7 @@ static Shader* find_cached_shader(ShaderCache* cache, uint64_t hash) { return 0; } -static ShaderProgram* find_cached_program(ProgramCache* cache, uint64_t hash) { +static ShaderProgram* find_cached_program(ProgramCache* cache, hash_t hash) { assert(cache); mempool_foreach(cache, entry, { if (entry->hash == hash) { @@ -350,9 +354,9 @@ Shader* gfx_make_shader(GfxCore* gfxcore, const ShaderDesc* desc) { assert(desc); // Check the shader cache first. - ShaderCache* cache = &gfxcore->shader_cache; - const uint64_t hash = hash_shader_desc(desc); - Shader* shader = find_cached_shader(cache, hash); + ShaderCache* cache = &gfxcore->shader_cache; + const hash_t hash = hash_shader_desc(desc); + Shader* shader = find_cached_shader(cache, hash); if (shader) { // LOGD("Found cached shader with hash [%lx]", hash); return shader; @@ -395,7 +399,7 @@ ShaderProgram* gfx_make_shader_program( // Check the shader program cache first. ProgramCache* cache = &gfxcore->program_cache; - const uint64_t hash = hash_program_desc(desc); + const hash_t hash = hash_program_desc(desc); ShaderProgram* prog = find_cached_program(cache, hash); if (prog) { // LOGD("Found cached shader program with hash [%lx]", hash); diff --git a/src/core/core_impl.h b/src/core/core_impl.h index eefdfbe..320532d 100644 --- a/src/core/core_impl.h +++ b/src/core/core_impl.h @@ -15,16 +15,18 @@ #include +typedef uint32_t hash_t; + // TODO: Make a generic (hash, void*) structure and define functions over it. // Then define a macro that defines type-safe macros given the type of the // entry. typedef struct ShaderCacheEntry { - uint64_t hash; - Shader* shader; + hash_t hash; + Shader* shader; } ShaderCacheEntry; typedef struct ShaderProgramCacheEntry { - uint64_t hash; + hash_t hash; ShaderProgram* program; } ShaderProgramCacheEntry; -- cgit v1.2.3