Work around issues with depth-buffer size on EGL-based platforms

The OpenGL 1.1 and OpenGL ES 2.0 backends can break on EGL-based platforms,
such as Wayland, or X11 with SDL_VIDEO_FORCE_EGL=1. One of the reasons for
this (the other being glew on the GL1.1 backend) is that SDL/egl get very
confused by the way we set OpenGL attributes, particularly SDL_GL_DEPTH_SIZE,
resulting in SDL_GL_CreateContext() failing with EGL_BAD_MATCH.

The exact cause of this is unknown, but it seems to be a combination of:
- SDL_GL_SetAttribute() is supposed to be called _before_ the window is
  created, and we're calling it afterward.
- Creating several test windows during the enumeration process, mixing
  and matching between OpenGL and OpenGL ES profiles.

The "most correct" solution is probably to delay creating the game window
until the backend creation process, rather than before the enumeration
occurs. But that's a real refactor, which could cause other issues.

Instead, set the 24-bit bit depth (which we've hardcoded anyway) before
creating the window, and use SDL_GL_ResetAttributes() when creating backends.

This seems to work here in all of the cases I was able to try (modulo the GLEW
dependency, which is removed in the next patch).
This commit is contained in:
David Gow 2025-06-29 12:08:01 +08:00
parent a987595e1e
commit 5fd6d51643
No known key found for this signature in database
GPG Key ID: C622A73A190CDB42
3 changed files with 13 additions and 4 deletions

View File

@ -660,6 +660,7 @@ MxResult IsleApp::SetupWindow()
#ifdef MINIWIN #ifdef MINIWIN
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
#endif #endif
window = SDL_CreateWindowWithProperties(props); window = SDL_CreateWindowWithProperties(props);

View File

@ -13,6 +13,12 @@
Direct3DRMRenderer* OpenGL1Renderer::Create(DWORD width, DWORD height) Direct3DRMRenderer* OpenGL1Renderer::Create(DWORD width, DWORD height)
{ {
// We have to reset the attributes here after having enumerated the
// OpenGL ES 2.0 renderer, or else SDL gets very confused by SDL_GL_DEPTH_SIZE
// call below when on an EGL-based backend, and crashes with EGL_BAD_MATCH.
SDL_GL_ResetAttributes();
// But ResetAttributes resets it to 16.
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
@ -28,8 +34,6 @@ Direct3DRMRenderer* OpenGL1Renderer::Create(DWORD width, DWORD height)
testWindow = true; testWindow = true;
} }
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GLContext context = SDL_GL_CreateContext(window); SDL_GLContext context = SDL_GL_CreateContext(window);
if (!context) { if (!context) {
SDL_Log("SDL_GL_CreateContext: %s", SDL_GetError()); SDL_Log("SDL_GL_CreateContext: %s", SDL_GetError());

View File

@ -30,6 +30,12 @@ struct SceneLightGLES2 {
Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
{ {
// We have to reset the attributes here after having enumerated the
// OpenGL ES 2.0 renderer, or else SDL gets very confused by SDL_GL_DEPTH_SIZE
// call below when on an EGL-based backend, and crashes with EGL_BAD_MATCH.
SDL_GL_ResetAttributes();
// But ResetAttributes resets it to 16.
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
@ -41,8 +47,6 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
testWindow = true; testWindow = true;
} }
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GLContext context = SDL_GL_CreateContext(window); SDL_GLContext context = SDL_GL_CreateContext(window);
if (!context) { if (!context) {
if (testWindow) { if (testWindow) {