Defer waiting for shader to be compiled to point of use

This commit is contained in:
goeiecool9999 2026-01-22 18:14:02 +01:00
parent aea9023ee9
commit edf6edde17
6 changed files with 47 additions and 36 deletions

View File

@ -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<RendererShaderGL*>(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;
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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

View File

@ -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)
{

View File

@ -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<class FileCache> s_programBinaryCache;
};