From d013582223d24619a302eca32cfa72f6284366ab Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 17 Jul 2024 21:53:19 +0300 Subject: [PATCH] Shadergen: Optimize caching --- include/PICA/pica_frag_config.hpp | 5 +++-- src/core/renderer_gl/renderer_gl.cpp | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/PICA/pica_frag_config.hpp b/include/PICA/pica_frag_config.hpp index 59f13757..9e13b3b5 100644 --- a/include/PICA/pica_frag_config.hpp +++ b/include/PICA/pica_frag_config.hpp @@ -24,8 +24,9 @@ namespace PICA { u32 texUnitConfig; u32 texEnvUpdateBuffer; - // There's 6 TEV stages, and each one is configured via 5 word-sized registers - std::array tevConfigs; + // There's 6 TEV stages, and each one is configured via 4 word-sized registers + // (+ the constant color register, which we don't include here, otherwise we'd generate too many shaders) + std::array tevConfigs; }; // Config used for identifying unique fragment pipeline configurations diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 0c33b898..249d8484 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -793,13 +793,19 @@ OpenGL::Program& RendererGL::getSpecializedShader() { texConfig.texUnitConfig = regs[InternalRegs::TexUnitCfg]; texConfig.texEnvUpdateBuffer = regs[InternalRegs::TexEnvUpdateBuffer]; - // Set up TEV stages - std::memcpy(&texConfig.tevConfigs[0 * 5], ®s[InternalRegs::TexEnv0Source], 5 * sizeof(u32)); - std::memcpy(&texConfig.tevConfigs[1 * 5], ®s[InternalRegs::TexEnv1Source], 5 * sizeof(u32)); - std::memcpy(&texConfig.tevConfigs[2 * 5], ®s[InternalRegs::TexEnv2Source], 5 * sizeof(u32)); - std::memcpy(&texConfig.tevConfigs[3 * 5], ®s[InternalRegs::TexEnv3Source], 5 * sizeof(u32)); - std::memcpy(&texConfig.tevConfigs[4 * 5], ®s[InternalRegs::TexEnv4Source], 5 * sizeof(u32)); - std::memcpy(&texConfig.tevConfigs[5 * 5], ®s[InternalRegs::TexEnv5Source], 5 * sizeof(u32)); + // Set up TEV stages. Annoyingly we can't just memcpy as the TEV registers are arranged like + // {Source, Operand, Combiner, Color, Scale} and we want to skip the color register since it's uploaded via UBO +#define setupTevStage(stage) \ + std::memcpy(&texConfig.tevConfigs[stage * 4], ®s[InternalRegs::TexEnv##stage##Source], 3 * sizeof(u32)); \ + texConfig.tevConfigs[stage * 4 + 3] = regs[InternalRegs::TexEnv##stage##Source + 5]; + + setupTevStage(0); + setupTevStage(1); + setupTevStage(2); + setupTevStage(3); + setupTevStage(4); + setupTevStage(5); +#undef setupTevStage CachedProgram& programEntry = shaderCache[fsConfig]; OpenGL::Program& program = programEntry.program;