[Feat] (MG_Impl): implement GLX 1.4 on the EGL layer so GLFW apps run on Linux

Desktop Linux GL apps (GLFW/LWJGL, glxgears, anything X11) create contexts
through GLX, and MobileGL only spoke EGL - the two exported glX symbols were
proc-address stubs that could resolve GL entry points but never produce a
context. GLXImpl is the missing sibling of WGLImpl/CGLImpl: the same
window-system-binding pattern, calling the internal MG_Impl::EGLImpl namespace
directly.

The surface covers exactly what GLFW 3.4 resolves via dlsym plus the legacy
visual API: FBConfig enumeration mirrors the two EGLState configs (stencil-8
first so stencil-wanting choosers land on it), glXGetVisualFromFBConfig answers
with the screen's default visual (falling back to any 24-bit TrueColor one),
and glXCreateContextAttribsARB maps the ARB attribs onto EGL context attribs
the way WGL's Ext_CreateContextAttribsARB does - profile mask only emitted for
3.2+ or an explicit profile request, since that bit is what keys MobileGL's
relaxed-semantics compatibility mode. Legacy glXCreateContext/CreateNewContext
hand out 3.3 compatibility contexts, matching wglCreateContext.

Drawables follow the WGL HWND model: the GLXWindow is the X window itself, the
EGL window surface is created lazily on first MakeCurrent and cached per XID,
and the GLX layer owns size discovery per the platform-layer contract - it
pushes changes through EGLImpl::ResizePlatformWindowSurface, polling
XGetGeometry on MakeCurrent and on swaps throttled to 250ms so a fast-swapping
app is not paying a server round trip per frame. libX11 is dlopen'd at runtime
like everywhere else in the tree; Xlib.h is already in every TU via the vulkan
include, so XVisualInfo gets an ABI mirror struct (Xutil.h needs the Bool and
Status macros that Includes.h deliberately pops) and the caller's XFree pairs
with our malloc.

glXGetProcAddress now resolves glX names from the export table before falling
through to the shared GL resolver, which previously returned nullptr for every
glX extension entry point - GLFW requires glXCreateContextAttribsARB and
glXSwapIntervalEXT to arrive that way.

Verified with a smoke test replaying GLFW's exact call sequence (dlsym-only
resolution, manual FBConfig filtering, 3.2 core forward-compatible context,
glXCreateWindow, 60 swapped frames, clean glGetError) on both backends against
the real NVIDIA driver, then with Minecraft 1.21.1, 1.21.4+Fabric+Sodium and
26.2-snapshot-6 reaching in-world rendering on both Espryt and Magma.
This commit is contained in:
BZLZHH
2026-08-05 23:08:29 -04:00
parent d39a706d57
commit 08f98ad9ce
5 changed files with 1455 additions and 4 deletions
+1
View File
@@ -206,6 +206,7 @@ set(SOURCE_FILES
MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp
MobileGL/MG_Impl/GLXImpl/Exporting/Definitions.cpp
MobileGL/MG_Impl/GLXImpl/GLXImpl.cpp
MobileGL/MG_Impl/GLXImpl/LookUp/LookUp.cpp
MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp