aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-11-01 14:22:34 -0700
committer3gg <3gg@shellblade.net>2025-11-01 14:22:34 -0700
commitf494baf976c4494dd0ea4e755907cf49b026eb5d (patch)
tree3df754e78b711e56cb5e4b775f2caa803ba93b0c
parentf2bac7f22ee0314edee5bee90d62d79afbd68171 (diff)
Better hashing of shaders
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/core/core.c36
-rw-r--r--src/core/core_impl.h8
3 files changed, 26 insertions, 19 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 44f679a..d028b70 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,6 +75,7 @@ target_compile_options(gfx PRIVATE -std=gnu11 -Wall -Wextra -Wpedantic)
75 75
76target_link_libraries(gfx PUBLIC 76target_link_libraries(gfx PUBLIC
77 cstring 77 cstring
78 hash
78 math) 79 math)
79 80
80target_link_libraries(gfx PRIVATE 81target_link_libraries(gfx PRIVATE
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 @@
3#include "gl_util.h" 3#include "gl_util.h"
4 4
5// #include <log/log.h> 5// #include <log/log.h>
6#include <fnv1a.h>
6 7
7#include <assert.h> 8#include <assert.h>
8 9
@@ -282,26 +283,29 @@ void gfx_destroy_framebuffer(GfxCore* gfxcore, FrameBuffer** framebuffer) {
282// Shaders. 283// Shaders.
283// ----------------------------------------------------------------------------- 284// -----------------------------------------------------------------------------
284 285
285static uint64_t hash_shader_desc(const ShaderDesc* desc) { 286static hash_t hash_shader_desc(const ShaderDesc* desc) {
286 assert(desc); 287 assert(desc);
287 // Note that defines may affect shader permutations, so we need to hash those 288 // Defines may affect shader permutations, so we need to hash those as well.
288 // as well. 289 hash_t hash = fnv1a32_begin();
289 uint64_t hash = 0; 290 hash = fnv1a32_update(hash, desc->code, strlen(desc->code));
290 for (size_t i = 0; i < desc->num_defines; ++i) { 291 for (size_t i = 0; i < desc->num_defines; ++i) {
291 const ShaderCompilerDefine* define = &desc->defines[i]; 292 const ShaderCompilerDefine* define = &desc->defines[i];
292 hash = (((hash << 13) + sstring_hash(define->name)) << 7) + 293
293 sstring_hash(define->value); 294 hash = fnv1a32_update(
295 hash, sstring_cstr(&define->name), sstring_length(&define->name));
296 hash = fnv1a32_update(
297 hash, sstring_cstr(&define->value), sstring_length(&define->value));
294 } 298 }
295 return (hash << 17) + cstring_hash(desc->code); 299 return hash;
296} 300}
297 301
298static uint64_t hash_program_desc(const ShaderProgramDesc* desc) { 302static hash_t hash_program_desc(const ShaderProgramDesc* desc) {
299 assert(desc); 303 assert(desc);
300 return ((uint64_t)desc->vertex_shader->id << 32) | 304 return ((hash_t)desc->vertex_shader->id << 16) |
301 (uint64_t)desc->fragment_shader->id; 305 (hash_t)desc->fragment_shader->id;
302} 306}
303 307
304static Shader* find_cached_shader(ShaderCache* cache, uint64_t hash) { 308static Shader* find_cached_shader(ShaderCache* cache, hash_t hash) {
305 assert(cache); 309 assert(cache);
306 mempool_foreach(cache, entry, { 310 mempool_foreach(cache, entry, {
307 if (entry->hash == hash) { 311 if (entry->hash == hash) {
@@ -311,7 +315,7 @@ static Shader* find_cached_shader(ShaderCache* cache, uint64_t hash) {
311 return 0; 315 return 0;
312} 316}
313 317
314static ShaderProgram* find_cached_program(ProgramCache* cache, uint64_t hash) { 318static ShaderProgram* find_cached_program(ProgramCache* cache, hash_t hash) {
315 assert(cache); 319 assert(cache);
316 mempool_foreach(cache, entry, { 320 mempool_foreach(cache, entry, {
317 if (entry->hash == hash) { 321 if (entry->hash == hash) {
@@ -350,9 +354,9 @@ Shader* gfx_make_shader(GfxCore* gfxcore, const ShaderDesc* desc) {
350 assert(desc); 354 assert(desc);
351 355
352 // Check the shader cache first. 356 // Check the shader cache first.
353 ShaderCache* cache = &gfxcore->shader_cache; 357 ShaderCache* cache = &gfxcore->shader_cache;
354 const uint64_t hash = hash_shader_desc(desc); 358 const hash_t hash = hash_shader_desc(desc);
355 Shader* shader = find_cached_shader(cache, hash); 359 Shader* shader = find_cached_shader(cache, hash);
356 if (shader) { 360 if (shader) {
357 // LOGD("Found cached shader with hash [%lx]", hash); 361 // LOGD("Found cached shader with hash [%lx]", hash);
358 return shader; 362 return shader;
@@ -395,7 +399,7 @@ ShaderProgram* gfx_make_shader_program(
395 399
396 // Check the shader program cache first. 400 // Check the shader program cache first.
397 ProgramCache* cache = &gfxcore->program_cache; 401 ProgramCache* cache = &gfxcore->program_cache;
398 const uint64_t hash = hash_program_desc(desc); 402 const hash_t hash = hash_program_desc(desc);
399 ShaderProgram* prog = find_cached_program(cache, hash); 403 ShaderProgram* prog = find_cached_program(cache, hash);
400 if (prog) { 404 if (prog) {
401 // LOGD("Found cached shader program with hash [%lx]", hash); 405 // 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 @@
15 15
16#include <stdint.h> 16#include <stdint.h>
17 17
18typedef uint32_t hash_t;
19
18// TODO: Make a generic (hash, void*) structure and define functions over it. 20// TODO: Make a generic (hash, void*) structure and define functions over it.
19// Then define a macro that defines type-safe macros given the type of the 21// Then define a macro that defines type-safe macros given the type of the
20// entry. 22// entry.
21typedef struct ShaderCacheEntry { 23typedef struct ShaderCacheEntry {
22 uint64_t hash; 24 hash_t hash;
23 Shader* shader; 25 Shader* shader;
24} ShaderCacheEntry; 26} ShaderCacheEntry;
25 27
26typedef struct ShaderProgramCacheEntry { 28typedef struct ShaderProgramCacheEntry {
27 uint64_t hash; 29 hash_t hash;
28 ShaderProgram* program; 30 ShaderProgram* program;
29} ShaderProgramCacheEntry; 31} ShaderProgramCacheEntry;
30 32