[Fix] (MG_Backend): let a default-visual X11 window match an alpha-free config

ChooseConfigForSurface prefilters candidate configs with eglChooseConfig
requiring EGL_ALPHA_SIZE 8, then tries to match the window's X visual. On
NVIDIA's X11 EGL every alpha-8 config lives on the 32-bit ARGB visual, and the
default depth-24 TrueColor visual only appears on alpha-0 configs - so for any
window created with the default visual the match loop scanned a list that
could not contain its visual, fell through to a 32-bit-visual config, and
eglCreateWindowSurface failed with EGL_BAD_CONFIG.

Keep the alpha-8 list as the first tier and add an alpha-relaxed second tier
used only for the visual match; the sizeless fallbacks below still run on the
alpha-8 list. Mesa is unaffected (its default-visual configs carry alpha), and
a destination-alpha-free default framebuffer is exactly what native GLX hands
out on these visuals anyway.

Found by running Minecraft through the new GLXImpl on Espryt: NVIDIA EGL also
needs EGL_PLATFORM=x11 under a Wayland session or eglGetDisplay itself returns
no display, which is a launcher-environment concern, not a library one.
This commit is contained in:
BZLZHH
2026-08-05 23:12:12 -04:00
parent 08f98ad9ce
commit 6e6f5268fb
+32 -7
View File
@@ -5678,19 +5678,44 @@ namespace MobileGL::MG_Backend::DirectGLES {
configs.resize(static_cast<SizeT>(numConfigs));
if (surfaceBit == EGL_WINDOW_BIT) {
// X11 drivers can reserve every alpha-8 config for 32-bit ARGB
// visuals (NVIDIA), so a default-visual (depth 24) window only
// matches an alpha-0 config; keep those as a second candidate tier
// for the visual match or eglCreateWindowSurface hits BAD_CONFIG.
Vector<EGLConfig> alphaFreeConfigs;
const EGLint alphaFreeAttribs[] = {EGL_SURFACE_TYPE, surfaceBit, EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES3_BIT,
EGL_RED_SIZE, 8, EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE,
24,
EGL_STENCIL_SIZE, 8, EGL_NONE};
EGLint numAlphaFree = 0;
if (g_EGLFuncs.eglChooseConfig(g_Display, alphaFreeAttribs, nullptr, 0, &numAlphaFree) &&
numAlphaFree > 0) {
alphaFreeConfigs.resize(static_cast<SizeT>(numAlphaFree));
if (!g_EGLFuncs.eglChooseConfig(g_Display, alphaFreeAttribs, alphaFreeConfigs.data(),
numAlphaFree, &numAlphaFree)) {
numAlphaFree = 0;
}
alphaFreeConfigs.resize(static_cast<SizeT>(numAlphaFree));
}
const EGLint windowVisualId = QueryX11WindowVisualId(window);
const EGLint visualIds[] = {windowVisualId, QueryDefaultX11VisualId()};
for (const auto visualId : visualIds) {
if (visualId == 0) {
continue;
}
for (const auto config : configs) {
EGLint nativeVisualId = 0;
if (ConfigSupports(config, surfaceBit) &&
GetConfigAttrib(config, EGL_NATIVE_VISUAL_ID, nativeVisualId) &&
nativeVisualId == visualId) {
outConfig = config;
return true;
for (const auto* candidates : {&configs, &alphaFreeConfigs}) {
for (const auto config : *candidates) {
EGLint nativeVisualId = 0;
if (ConfigSupports(config, surfaceBit) &&
GetConfigAttrib(config, EGL_NATIVE_VISUAL_ID, nativeVisualId) &&
nativeVisualId == visualId) {
outConfig = config;
return true;
}
}
}
}