From edf6edde177b050747f3679bec987fadffea1527 Mon Sep 17 00:00:00 2001 From: goeiecool9999 <7033575+goeiecool9999@users.noreply.github.com> Date: Thu, 22 Jan 2026 18:14:02 +0100 Subject: [PATCH] Defer waiting for shader to be compiled to point of use --- src/Cafe/HW/Latte/Core/LatteShader.cpp | 27 ++++------------- src/Cafe/HW/Latte/Core/LatteShaderCache.cpp | 4 --- src/Cafe/HW/Latte/Core/LatteShaderGL.cpp | 2 -- .../Renderer/OpenGL/OpenGLRendererCore.cpp | 17 +++++++++-- .../Renderer/OpenGL/RendererShaderGL.cpp | 29 +++++++++++++++---- .../Latte/Renderer/OpenGL/RendererShaderGL.h | 4 +++ 6 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/Cafe/HW/Latte/Core/LatteShader.cpp b/src/Cafe/HW/Latte/Core/LatteShader.cpp index 595230d7..54c5acc1 100644 --- a/src/Cafe/HW/Latte/Core/LatteShader.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShader.cpp @@ -14,6 +14,7 @@ #include "util/helpers/StringParser.h" #include "config/ActiveSettings.h" #include "Cafe/GameProfile/GameProfile.h" +#include "HW/Latte/Renderer/OpenGL/RendererShaderGL.h" #include "util/containers/flat_hash_map.hpp" #if ENABLE_METAL #include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h" @@ -363,6 +364,11 @@ void LatteShader_CreateRendererShader(LatteDecompilerShader* shader, bool compil shader->shader = g_renderer->shader_create(shaderType, shader->baseHash, shader->auxHash, std::move(shaderSrc), true, shader->isCustomShader); if (shader->shader == nullptr) shader->hasError = true; + if (g_renderer->GetType() == RendererAPI::OpenGL) + { + RendererShaderGL* shaderGL = static_cast(shader->shader); + shaderGL->SetDecompilerShader(shader); + } // after renderer shader creation we can throw away any intermediate info LatteShader_CleanupAfterCompile(shader); } @@ -832,13 +838,6 @@ LatteDecompilerShader* LatteShader_CompileSeparableVertexShader(uint64 baseHash, LatteShader_CreateRendererShader(vertexShader, false); performanceMonitor.numCompiledVS++; - if (g_renderer->GetType() == RendererAPI::OpenGL) - { - if (vertexShader->shader) - vertexShader->shader->PreponeCompilation(); - LatteShader_prepareSeparableUniforms(vertexShader); - } - LatteSHRC_RegisterShader(vertexShader, vertexShader->baseHash, vertexShader->auxHash); return vertexShader; } @@ -861,13 +860,6 @@ LatteDecompilerShader* LatteShader_CompileSeparableGeometryShader(uint64 baseHas LatteShader_CreateRendererShader(geometryShader, false); performanceMonitor.numCompiledGS++; - if (g_renderer->GetType() == RendererAPI::OpenGL) - { - if (geometryShader->shader) - geometryShader->shader->PreponeCompilation(); - LatteShader_prepareSeparableUniforms(geometryShader); - } - LatteSHRC_RegisterShader(geometryShader, geometryShader->baseHash, geometryShader->auxHash); return geometryShader; } @@ -890,13 +882,6 @@ LatteDecompilerShader* LatteShader_CompileSeparablePixelShader(uint64 baseHash, LatteShaderCache_writeSeparablePixelShader(_shaderBaseHash_ps, psAuxHash, pixelShaderPtr, pixelShaderSize, LatteGPUState.contextRegister, usesGeometryShader); } - if (g_renderer->GetType() == RendererAPI::OpenGL) - { - if (pixelShader->shader) - pixelShader->shader->PreponeCompilation(); - LatteShader_prepareSeparableUniforms(pixelShader); - } - LatteSHRC_RegisterShader(pixelShader, _shaderBaseHash_ps, psAuxHash); return pixelShader; } diff --git a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp index 89763c67..305e3011 100644 --- a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp @@ -114,7 +114,6 @@ void LatteShaderCache_updateCompileQueue(sint32 maxRemainingEntries) continue; if (shaderEntry->shader->IsCompiled()) { - LatteShader_prepareSeparableUniforms(shaderEntry); LatteShaderCache_removeFromCompileQueue(i); } } @@ -124,10 +123,7 @@ void LatteShaderCache_updateCompileQueue(sint32 maxRemainingEntries) break; auto shader = shaderCompileQueue.entry[0].shader; if (shader) - { shader->shader->PreponeCompilation(); - LatteShader_prepareSeparableUniforms(shader); - } LatteShaderCache_removeFromCompileQueue(0); } } diff --git a/src/Cafe/HW/Latte/Core/LatteShaderGL.cpp b/src/Cafe/HW/Latte/Core/LatteShaderGL.cpp index c5e0a05b..7a22539a 100644 --- a/src/Cafe/HW/Latte/Core/LatteShaderGL.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShaderGL.cpp @@ -26,8 +26,6 @@ bool gxShader_checkIfSuccessfullyLinked(GLuint glProgram) void LatteShader_prepareSeparableUniforms(LatteDecompilerShader* shader) { - if (g_renderer->GetType() != RendererAPI::OpenGL) - return; if(shader->hasError) return; diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp index fb524be1..821252d3 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp @@ -912,9 +912,20 @@ void OpenGLRenderer::draw_genericDrawHandler(uint32 baseVertex, uint32 baseInsta { beginPerfMonProfiling(performanceMonitor.gpuTime_dcStageShaderAndUniformMgr); LatteSHRC_UpdateActiveShaders(); - LatteDecompilerShader* vs = (LatteDecompilerShader*)LatteSHRC_GetActiveVertexShader(); - LatteDecompilerShader* gs = (LatteDecompilerShader*)LatteSHRC_GetActiveGeometryShader(); - LatteDecompilerShader* ps = (LatteDecompilerShader*)LatteSHRC_GetActivePixelShader(); + LatteDecompilerShader* vs = LatteSHRC_GetActiveVertexShader(); + LatteDecompilerShader* gs = LatteSHRC_GetActiveGeometryShader(); + LatteDecompilerShader* ps = LatteSHRC_GetActivePixelShader(); + + for (auto& i : {vs, gs, ps}) + { + if (!i) + continue; + if (!i->shader->IsCompiled()) + { + i->shader->WaitForCompiled(); + } + } + if (vs) shader_bind(vs->shader); else diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.cpp index fa343c5c..31034222 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.cpp @@ -2,6 +2,7 @@ #include "Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h" #include "Cemu/FileCache/FileCache.h" +#include "HW/Latte/Core/LatteShader.h" #include "config/ActiveSettings.h" #include "config/LaunchSettings.h" @@ -42,7 +43,7 @@ bool RendererShaderGL::loadBinary() m_program = 0; return false; } - m_isCompiled = true; + m_binaryLoaded = true; return true; } @@ -154,7 +155,7 @@ bool RendererShaderGL::IsCompiled() if(m_isCompiled) return true; - if(!glMaxShaderCompilerThreadsARB) + if(!glMaxShaderCompilerThreadsARB || m_binaryLoaded) { WaitForCompiled(); return true; @@ -172,10 +173,17 @@ bool RendererShaderGL::IsCompiled() bool RendererShaderGL::WaitForCompiled() { - char infoLog[8 * 1024]; - GLint log_length; if (m_isCompiled) return true; + if (m_binaryLoaded) + { + LatteShader_prepareSeparableUniforms(m_decompilerShader); + m_isCompiled = true; + return true; + } + + char infoLog[8 * 1024]; + GLint log_length; // count shader compilation if (!s_isLoadingShaders) @@ -219,14 +227,19 @@ bool RendererShaderGL::WaitForCompiled() return false; } - storeBinary(); - glDetachShader(m_program, m_shader_object); m_shader_attached = false; glDeleteShader(m_shader_object); m_shader_object = 0; + storeBinary(); + m_isCompiled = true; + if (m_decompilerShader) + { + LatteShader_prepareSeparableUniforms(m_decompilerShader); + } + return true; } @@ -254,6 +267,10 @@ void RendererShaderGL::SetUniform4iv(sint32 location, void* data, sint32 count) { glProgramUniform4iv(m_program, location, count, (const GLint*)data); } +void RendererShaderGL::SetDecompilerShader(LatteDecompilerShader* decompilerShader) +{ + m_decompilerShader = decompilerShader; +} void RendererShaderGL::ShaderCacheLoading_begin(uint64 cacheTitleId) { diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h b/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h index 31f6b827..2d4f986b 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h @@ -24,6 +24,8 @@ public: void SetUniform2fv(sint32 location, void* data, sint32 count); void SetUniform4iv(sint32 location, void* data, sint32 count); + void SetDecompilerShader(class LatteDecompilerShader* decompilerShader); + static void ShaderCacheLoading_begin(uint64 cacheTitleId); static void ShaderCacheLoading_end(); static void ShaderCacheLoading_Close(); @@ -31,6 +33,7 @@ public: private: GLuint m_program; GLuint m_shader_object; + LatteDecompilerShader* m_decompilerShader = nullptr; bool loadBinary(); void storeBinary(); @@ -39,6 +42,7 @@ private: bool m_shader_attached{ false }; bool m_isCompiled{ false }; + bool m_binaryLoaded { false }; static std::unique_ptr s_programBinaryCache; };