From 657b590b6fc57bcfbefaf5db27714a5b1920269e Mon Sep 17 00:00:00 2001 From: asrael Date: Sat, 7 Feb 2026 20:08:22 -0600 Subject: [PATCH] wire up pipeline cache --- src/core/pxl8.c | 1 + src/gfx/pxl8_render.c | 53 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/core/pxl8.c b/src/core/pxl8.c index 758efb8..1895703 100644 --- a/src/core/pxl8.c +++ b/src/core/pxl8.c @@ -283,6 +283,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) { } #ifndef NDEBUG + game->debug_stats = true; game->debug_replay = pxl8_replay_create_buffer(60, 60); pxl8_sfx_mixer_set_event_callback(game->mixer, pxl8_audio_event_callback, game); #endif diff --git a/src/gfx/pxl8_render.c b/src/gfx/pxl8_render.c index 76417e7..2ecf566 100644 --- a/src/gfx/pxl8_render.c +++ b/src/gfx/pxl8_render.c @@ -734,6 +734,27 @@ typedef struct { bool valid; } pipeline_cache_entry; +static u32 pipeline_desc_hash(const pxl8_gfx_pipeline_desc* d) { + u32 h = 2166136261u; + h = (h ^ (u32)d->blend.enabled) * 16777619u; + h = (h ^ (u32)d->blend.src) * 16777619u; + h = (h ^ (u32)d->blend.dst) * 16777619u; + h = (h ^ (u32)d->blend.alpha_test) * 16777619u; + h = (h ^ (u32)d->blend.alpha_ref) * 16777619u; + h = (h ^ (u32)d->depth.test) * 16777619u; + h = (h ^ (u32)d->depth.write) * 16777619u; + h = (h ^ (u32)d->depth.compare) * 16777619u; + h = (h ^ (u32)d->dither) * 16777619u; + h = (h ^ (u32)d->double_sided) * 16777619u; + h = (h ^ (u32)d->emissive) * 16777619u; + h = (h ^ (u32)d->rasterizer.cull) * 16777619u; + h = (h ^ (u32)d->rasterizer.fill) * 16777619u; + u64 s = (u64)(uintptr_t)d->shader; + h = (h ^ (u32)s) * 16777619u; + h = (h ^ (u32)(s >> 32)) * 16777619u; + return h; +} + typedef struct { pxl8_gfx_pipeline_desc desc; u16 generation; @@ -900,12 +921,39 @@ pxl8_gfx_buffer pxl8_create_buffer(pxl8_renderer* r, const pxl8_gfx_buffer_desc* } pxl8_gfx_pipeline pxl8_create_pipeline(pxl8_renderer* r, const pxl8_gfx_pipeline_desc* desc) { + u32 hash = pipeline_desc_hash(desc); + u32 bucket = hash & (PXL8_PIPELINE_CACHE_SIZE - 1); + pipeline_cache_entry* ce = &r->pipeline_cache[bucket]; + + if (ce->valid && ce->hash == hash) { + pipeline_slot* s = &r->pipelines[ce->slot_idx]; + if (s->active && s->cached) { + ce->last_used_frame = r->frame_counter; + return (pxl8_gfx_pipeline){ MAKE_ID(ce->slot_idx, s->generation) }; + } + } + for (u32 i = 0; i < PXL8_GFX_MAX_PIPELINES; i++) { if (!r->pipelines[i].active) { pipeline_slot* s = &r->pipelines[i]; s->desc = *desc; s->generation = NEXT_GEN(s->generation); s->active = true; + + if (!ce->valid || ce->last_used_frame != r->frame_counter) { + if (ce->valid && ce->slot_idx < PXL8_GFX_MAX_PIPELINES) { + r->pipelines[ce->slot_idx].cached = false; + r->pipelines[ce->slot_idx].active = false; + } + s->cached = true; + ce->hash = hash; + ce->slot_idx = i; + ce->last_used_frame = r->frame_counter; + ce->valid = true; + } else { + s->cached = false; + } + return (pxl8_gfx_pipeline){ MAKE_ID(i, s->generation) }; } } @@ -980,7 +1028,8 @@ void pxl8_destroy_buffer(pxl8_renderer* r, pxl8_gfx_buffer buf) { void pxl8_destroy_pipeline(pxl8_renderer* r, pxl8_gfx_pipeline pip) { u32 idx = SLOT_INDEX(pip.id); if (idx < PXL8_GFX_MAX_PIPELINES && r->pipelines[idx].generation == SLOT_GEN(pip.id)) { - r->pipelines[idx].active = false; + if (!r->pipelines[idx].cached) + r->pipelines[idx].active = false; } } @@ -1415,6 +1464,8 @@ void pxl8_gfx_submit(pxl8_renderer* r, pxl8_gfx_cmdbuf* cb) { r->buffers[i].append_pos = 0; } } + + r->frame_counter++; } void pxl8_clear(pxl8_renderer* r, pxl8_gfx_texture target, u8 color) {