godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.79k stars 20.13k forks source link

Godot crashing after failing to obtain an OpenGL context when OpenGL 3.3 is not supported #74522

Closed Robson96 closed 1 year ago

Robson96 commented 1 year ago

Godot version

4.0

System information

ubuntu 22.04 x64 intel dual core 4gb ram

Issue description

Godot Engine v4.0.stable.official.92bee43ad - https://godotengine.org

X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  149 (GLX)
  Minor opcode of failed request:  0 ()
  Serial number of failed request:  29
  Current serial number in output stream:  29
ERROR: BUG: Unreferenced static string to 0: interface_added
   at: unref (core/string/string_name.cpp:131)
X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  149 (GLX)
  Minor opcode of failed request:  0 ()
  Serial number of failed request:  29
  Current serial number in output stream:  29
ERROR: BUG: Unreferenced static string to 0: interface_added
   at: unref (core/string/string_name.cpp:131)
ERROR: Condition "ctxErrorOccurred || !gl_display.context->glx_context" is true. Returning: ERR_UNCONFIGURED
   at: _create_context (platform/linuxbsd/x11/gl_manager_x11.cpp:176)

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.0.stable.official (92bee43adba8d2401ef40e2480e53087bcb1eaf1)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /lib/x86_64-linux-gnu/libc.so.6(+0x42520) [0x7f98ec842520] (??:0)
[2] ./Godot_v4.0-stable_linux.x86_64() [0xe8cad5] (??:0)
[3] ./Godot_v4.0-stable_linux.x86_64() [0xe9b06d] (??:0)
[4] ./Godot_v4.0-stable_linux.x86_64() [0xe9bf3e] (??:0)
[5] ./Godot_v4.0-stable_linux.x86_64() [0x49e3051] (??:0)
[6] ./Godot_v4.0-stable_linux.x86_64() [0xe09825] (??:0)
[7] /lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7f98ec829d90] (??:0)
[8] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7f98ec829e40] (??:0)
[9] ./Godot_v4.0-stable_linux.x86_64() [0xe2286e] (??:0)
-- END OF BACKTRACE --
================================================================
Abortado

Steps to reproduce

$ ./Godot_v4.0-stable_linux.x86_64

Minimal reproduction project

no

clayjohn commented 1 year ago

Does your computer support OpenGL 3.3? It looks like Godot is crashing after failing to aquire an OpenGL 3.3 context.

Could you provide more information about your hardware and your GPU drivers?

Robson96 commented 1 year ago
~$ inxi -G
Graphics:
  Device-1: Intel Mobile GM965/GL960 Integrated Graphics driver: i915
    v: kernel
  Display: wayland server: X.Org v: 1.22.1.1 with: Xwayland v: 22.1.1
    compositor: gnome-shell v: 42.5 driver: X: loaded: modesetting
    unloaded: fbdev,vesa gpu: i915 resolution: 1280x800~60Hz
  OpenGL: renderer: Mesa Intel 965GM (CL) v: 2.1 Mesa 22.2.5
Robson96 commented 1 year ago
~$ glxinfo | grep "OpenGL"
OpenGL vendor string: Intel
OpenGL renderer string: Mesa Intel(R) 965GM (CL)
OpenGL version string: 2.1 Mesa 22.2.5
OpenGL shading language version string: 1.20
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 2.0 Mesa 22.2.5
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 1.0.16
OpenGL ES profile extensions:
akien-mga commented 1 year ago

Thanks, I can confirm the crash indeed when forcing Mesa to downgrade my supported OpenGL version to 2.1 (with MESA_GL_VERSION_OVERRIDE=2.1):

(gdb) r
Starting program: /home/akien/.local/bin/godot-git bt
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[Detaching after vfork from child process 99182]
[New Thread 0x7ffff5fff6c0 (LWP 99184)]
[New Thread 0x7ffff57fe6c0 (LWP 99185)]
[New Thread 0x7ffff4ffd6c0 (LWP 99186)]
[New Thread 0x7ffff47fc6c0 (LWP 99187)]
[New Thread 0x7ffff3ffb6c0 (LWP 99188)]
[New Thread 0x7ffff37fa6c0 (LWP 99189)]
[New Thread 0x7ffff2ff96c0 (LWP 99190)]
[New Thread 0x7ffff27f86c0 (LWP 99191)]
[New Thread 0x7ffff1ff76c0 (LWP 99192)]
Godot Engine v4.1.dev.custom_build.013a45706 - https://godotengine.org
[New Thread 0x7ffff11106c0 (LWP 99194)]
[Detaching after fork from child process 99195]
[Detaching after fork from child process 99196]
X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  152 (GLX)
  Minor opcode of failed request:  0 ()
  Serial number of failed request:  32
  Current serial number in output stream:  32
ERROR: BUG: Unreferenced static string to 0: interface_added
   at: unref (core/string/string_name.cpp:131)
[Detaching after fork from child process 99233]
X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  152 (GLX)
  Minor opcode of failed request:  0 ()
  Serial number of failed request:  32
  Current serial number in output stream:  32
ERROR: BUG: Unreferenced static string to 0: interface_added
   at: unref (core/string/string_name.cpp:131)
[New Thread 0x7fffebfff6c0 (LWP 99246)]
[Thread 0x7ffff11106c0 (LWP 99194) exited]
[New Thread 0x7fffe99ff6c0 (LWP 99247)]
[New Thread 0x7fffe91fe6c0 (LWP 99248)]
[New Thread 0x7fffe89fd6c0 (LWP 99249)]
[New Thread 0x7fffde7ff6c0 (LWP 99250)]
[New Thread 0x7fffddffe6c0 (LWP 99251)]
[New Thread 0x7fffdd7fd6c0 (LWP 99252)]
[New Thread 0x7fffdcffc6c0 (LWP 99253)]
ERROR: Condition "ctxErrorOccurred || !gl_display.context->glx_context" is true. Returning: ERR_UNCONFIGURED
   at: _create_context (platform/linuxbsd/x11/gl_manager_x11.cpp:176)

Thread 1 "godot-git" received signal SIGSEGV, Segmentation fault.
DisplayServerX11::_create_window (this=0xc30da60, p_mode=DisplayServer::WINDOW_MODE_WINDOWED, p_vsync_mode=DisplayServer::VSYNC_ENABLED, p_flags=0, p_rect=...) at platform/linuxbsd/x11/display_server_x11.cpp:4929
4929            Colormap colormap = XCreateColormap(x11_display, RootWindow(x11_display, visualInfo.screen), visualInfo.visual, AllocNone);

(gdb) bt
#0  DisplayServerX11::_create_window (this=0xc30da60, p_mode=DisplayServer::WINDOW_MODE_WINDOWED, p_vsync_mode=DisplayServer::VSYNC_ENABLED, p_flags=0, p_rect=...)
    at platform/linuxbsd/x11/display_server_x11.cpp:4929
#1  0x000000000530b74a in DisplayServerX11::DisplayServerX11 (this=0xc30da60, p_rendering_driver=..., p_mode=DisplayServer::WINDOW_MODE_WINDOWED, p_vsync_mode=DisplayServer::VSYNC_ENABLED, p_flags=0, 
    p_position=0x0, p_resolution=..., p_screen=-2, r_error=@0x7fffffffa72c: OK) at platform/linuxbsd/x11/display_server_x11.cpp:5573
#2  0x000000000530866c in DisplayServerX11::create_func (p_rendering_driver=..., p_mode=DisplayServer::WINDOW_MODE_WINDOWED, p_vsync_mode=DisplayServer::VSYNC_ENABLED, p_flags=0, p_position=0x0, 
    p_resolution=..., p_screen=-2, r_error=@0x7fffffffa72c: OK) at platform/linuxbsd/x11/display_server_x11.cpp:4869
#3  0x00000000093fe98e in DisplayServer::create (p_index=0, p_rendering_driver=..., p_mode=DisplayServer::WINDOW_MODE_WINDOWED, p_vsync_mode=DisplayServer::VSYNC_ENABLED, p_flags=0, p_position=0x0, 
    p_resolution=..., p_screen=-2, r_error=@0x7fffffffa72c: OK) at servers/display_server.cpp:906
#4  0x000000000535b8c7 in Main::setup2 (p_main_tid_override=0) at main/main.cpp:1996
#5  0x0000000005359282 in Main::setup (execpath=0x7fffffffdb76 "/home/akien/.local/bin/godot-git", argc=1, argv=0x7fffffffd6f0, p_second_phase=true) at main/main.cpp:1874
#6  0x00000000052ded65 in main (argc=2, argv=0x7fffffffd6e8) at platform/linuxbsd/godot_linuxbsd.cpp:61

For the record @Robson96, you won't be able to run Godot 4.0 even after we fix this crash. The proper behavior on your hardware will be that it will say your graphics processor is too low end for Godot, as OpenGL 3.3 is the minimum requirement.

You can keep using Godot 3.x with the GLES2 renderer though, which should work (but possibly with bugs, the drivers for this old Intel chipset aren't the best).

Still, this crash needs to be solved so it errors properly.

akien-mga commented 1 year ago

The problem is that we don't do any validation that the GL context is suitable:

GLManager_X11::ContextType opengl_api_type = GLManager_X11::GLES_3_0_COMPATIBLE;

gl_manager = memnew(GLManager_X11(p_resolution, opengl_api_type));

if (gl_manager->initialize(x11_display) != OK) {
    memdelete(gl_manager);
    gl_manager = nullptr;
    r_error = ERR_UNAVAILABLE;
    return;
}
driver_found = true;

if (true) {
    RasterizerGLES3::make_current();
} else {
    memdelete(gl_manager);
    gl_manager = nullptr;
    r_error = ERR_UNAVAILABLE;
    return;
}

In 3.x, this if (true) used to be RasterizerGLES3::is_viable(), but we no longer have this method.

Robson96 commented 1 year ago

I understand, I'm glad it can help you developers.

akien-mga commented 1 year ago

As I mentioned, this is a valid bug and we need to fix it :)

akien-mga commented 1 year ago

I had a go at fixing this but didn't manage.

I have a WIP branch which I believe cleans up the code and improves it, and attempts to add some GL version checks, but it's not working: https://github.com/akien-mga/godot/tree/opengl-fix-gl-context-validation

The problem is that when we create GLManager_X11 and initialize it, a call to glLoaderLoadGL() would return 0. It seems to need a window to have been created in the GLX context. But when the window attempts being created, it calls GLManager_X11::get_vi(), which creates a display without proper error handling.

It raises an unrecoverable error here:

    switch (context_type) {
        case GLES_3_0_COMPATIBLE: {
            static int context_attribs[] = {
                GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
                GLX_CONTEXT_MINOR_VERSION_ARB, 3,
                GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
                GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*|GLX_CONTEXT_DEBUG_BIT_ARB*/,
                None
            };

            gl_display.context->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, nullptr, true, context_attribs);
            ERR_FAIL_COND_V(ctxErrorOccurred || !gl_display.context->glx_context, ERR_UNCONFIGURED);
        } break;
    }

Because indeed, that's the first time we attempt to validate the GL version and it's not working. But at this stage there's no recovery, so crash.