GL: delay shader error check and program linking to improve parallel shader compilation

This commit is contained in:
goeiecool9999 2025-07-24 09:45:02 +02:00
parent a96435a5dd
commit 328509e719

View file

@ -109,17 +109,6 @@ RendererShaderGL::RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxH
glShaderSource(m_shader_object, 1, &c_str, &size);
glCompileShader(m_shader_object);
GLint log_length;
glGetShaderiv(m_shader_object, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
char log[2048]{};
GLsizei log_size;
glGetShaderInfoLog(m_shader_object, std::min<uint32>(log_length, sizeof(log) - 1), &log_size, log);
cemuLog_log(LogType::Force, "Error/Warning in shader:");
cemuLog_log(LogType::Force, log);
}
// set debug name
if (LaunchSettings::NSightModeEnabled())
{
@ -127,19 +116,6 @@ RendererShaderGL::RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxH
glObjectLabel(GL_SHADER, m_shader_object, objNameStr.size(), objNameStr.c_str());
}
m_program = glCreateProgram();
glProgramParameteri(m_program, GL_PROGRAM_SEPARABLE, GL_TRUE);
glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
glAttachShader(m_program, m_shader_object);
m_shader_attached = true;
glLinkProgram(m_program);
storeBinary();
// count shader compilation
if (!s_isLoadingShaders)
++g_compiled_shaders_total;
// we can throw away the GLSL code to conserve RAM
m_glslSource.clear();
m_glslSource.shrink_to_fit();
@ -168,47 +144,61 @@ void RendererShaderGL::PreponeCompilation()
bool RendererShaderGL::IsCompiled()
{
cemu_assert_debug(false);
if(m_isCompiled)
return true;
GLint isShaderComplete;
glGetShaderiv(m_shader_object, GL_COMPLETION_STATUS_ARB, &isShaderComplete);
if(isShaderComplete)
WaitForCompiled(); // since COMPLETION_STATUS == true, this should be very fast
return m_isCompiled;
}
bool RendererShaderGL::WaitForCompiled()
{
char infoLog[8 * 1024];
GLint log_length;
if (m_isCompiled)
return true;
// count shader compilation
if (!s_isLoadingShaders)
++g_compiled_shaders_total;
// check if compilation was successful
GLint compileStatus = GL_FALSE;
glGetShaderiv(m_shader_object, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus == 0)
if (compileStatus == GL_FALSE)
{
uint32 infoLogLength, tempLength;
glGetShaderiv(m_shader_object, GL_INFO_LOG_LENGTH, (GLint *)&infoLogLength);
if (infoLogLength != 0)
glGetShaderiv(m_shader_object, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
tempLength = sizeof(infoLog) - 1;
glGetShaderInfoLog(m_shader_object, std::min(infoLogLength, tempLength), (GLsizei*)&tempLength, (GLcharARB*)infoLog);
infoLog[tempLength] = '\0';
cemuLog_log(LogType::Force, "Compile error in shader. Log:");
glGetShaderInfoLog(m_shader_object, sizeof(infoLog), &log_length, infoLog);
cemuLog_log(LogType::Force, "Error/Warning in shader:");
cemuLog_log(LogType::Force, infoLog);
}
if (m_shader_object != 0)
glDeleteShader(m_shader_object);
m_isCompiled = true;
return false;
}
m_program = glCreateProgram();
glProgramParameteri(m_program, GL_PROGRAM_SEPARABLE, GL_TRUE);
glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
glAttachShader(m_program, m_shader_object);
m_shader_attached = true;
glLinkProgram(m_program);
// get shader binary
GLint linkStatus = GL_FALSE;
glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus);
if (linkStatus == 0)
if (linkStatus == GL_FALSE)
{
uint32 infoLogLength, tempLength;
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, (GLint *)&infoLogLength);
if (infoLogLength != 0)
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, (GLint *)&log_length);
if (log_length != 0)
{
tempLength = sizeof(infoLog) - 1;
glGetProgramInfoLog(m_program, std::min(infoLogLength, tempLength), (GLsizei*)&tempLength, (GLcharARB*)infoLog);
infoLog[tempLength] = '\0';
glGetProgramInfoLog(m_program, sizeof(infoLog), &log_length, (GLcharARB*)infoLog);
cemuLog_log(LogType::Force, "Link error in shader. Log:");
cemuLog_log(LogType::Force, infoLog);
}
@ -216,8 +206,13 @@ bool RendererShaderGL::WaitForCompiled()
return false;
}
/*glDetachShader(m_program, m_shader_object);
m_shader_attached = false;*/
storeBinary();
glDetachShader(m_program, m_shader_object);
m_shader_attached = false;
glDeleteShader(m_shader_object);
m_shader_object = 0;
m_isCompiled = true;
return true;
}