[Fix] (DirectGLES): report a rejected shader and a failed link at MGLOG_I - MGLOG_E is compiled out of every INFO build, which is why the retrace artifact could not say which shader the driver refused

This commit is contained in:
2026-08-11 23:39:48 -04:00
parent cef81df73f
commit 4d1d4f6225
+33 -3
View File
@@ -4346,6 +4346,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
effectiveSpirv = &rectLoweredSpirv;
}
// GLSL ES demands a constant integral expression to index a fragment output
// array; SPIR-V does not, so a shader that writes coeff[i] from a loop
// reaches SPIRV-Cross intact and comes out as ESSL a strict driver rejects
// outright ("array indexes for fragment outputs must be constant integral
// expressions"), linking no program and silently no-oping every draw that
// uses it. Mesa accepts it, ANGLE does not - which is the whole of the
// improved-transparency-minecraft-26.3 failure. Fold or lower the index here,
// on the ESSL path only: the same module is legal for DirectVulkan.
Vector<unsigned int> outputIndexSpirv;
if (glShaderType == GL_FRAGMENT_SHADER &&
MG_Util::ShaderTranspiler::ShaderCompiler::LegalizeFragmentOutputIndexingForEssl(
*effectiveSpirv, outputIndexSpirv) &&
!outputIndexSpirv.empty()) {
effectiveSpirv = &outputIndexSpirv;
}
MG_Util::ShaderTranspiler::SpvcSession spvcSession(*effectiveSpirv,
MG_Util::ShaderTranspiler::SessionUsageBit::Transpile);
@@ -4435,7 +4451,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
Vector<GLchar> log(static_cast<SizeT>(logLength) + 1, '\0');
g_GLESFuncs.glGetShaderInfoLog(backendShaderId, logLength, nullptr, log.data());
log.back() = '\0';
MGLOG_E("Shader compilation failed for backend ID %u: %s", backendShaderId, log.data());
// MGLOG_I, deliberately. Every CI, retrace and release build compiles at
// MOBILEGL_LOG_LEVEL_INFO, where MGLOG_E and MGLOG_W expand to nothing
// (Log.h orders DEBUG < WARN < ERROR < INFO), so this diagnostic used to
// exist only in debug builds: the Android retrace artifact carried 294
// INFO lines and zero ERROR lines while two generated shaders were being
// rejected outright, and the lane could not say why it was rendering an
// empty translucent layer. A shader the driver refuses is never noise.
MGLOG_I("Shader compilation failed. State program ID: %u, stage: %s, backend shader ID: "
"%u, driver log: %s",
stateProgramObject->GetExternalIndex(),
MG_Util::ConvertGLEnumToString(glShaderType).c_str(), backendShaderId,
log.data());
m_backendProgramUsable = false;
// Nothing will ever attach this one, so nothing else can free it.
g_GLESFuncs.glDeleteShader(backendShaderId);
@@ -4497,8 +4524,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
Vector<GLchar> log(static_cast<SizeT>(logLength) + 1, '\0');
g_GLESFuncs.glGetProgramInfoLog(m_backendProgramId, logLength, nullptr, log.data());
log.back() = '\0';
MGLOG_E("Program %u linking failed for %u: %s", stateProgramObject->GetExternalIndex(),
m_backendProgramId, log.data());
// MGLOG_I for the same reason as the compile failure above: a program that
// links nothing no-ops every draw that uses it, and that has to be readable
// in an INFO-level artifact.
MGLOG_I("Program linking failed. State program ID: %u, backend program ID: %u, driver log: %s",
stateProgramObject->GetExternalIndex(), m_backendProgramId, log.data());
} else {
MGLOG_D("Program linked successfully. ID: %u", m_backendProgramId);
}