godotengine / godot

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

AMD iGPU gets prefered over Intel dGPU (Linux `detect_prime`) #99241

Open bl4ckb0ne opened 2 days ago

bl4ckb0ne commented 2 days ago

Tested versions

Found using Godot_v4.3-stable_linux.x86_64 but I still see the issue in master

System information

Debian trixie (6.11.4-1), Godot 4.3

Issue description

On my system with 2 GPUs (Intel dGPU and AMD iGPU), Godot will prefer the AMD GPU over the Intel GPU based on the priority from the vendor_map here 1. My iGPU is not connected to anything, so Godot fails to create a surface to render to and crashes.

There's currently no way to override this behaviour.

Steps to reproduce

Found renderers:
Renderer 0: Mesa Intel(R) Arc(tm) A750 Graphics (DG2) with priority: 20
Renderer 1: AMD Radeon Graphics (radeonsi, renoir, LLVM 19.1.3, DRM 3.59, 6.11.4-amd64) with priority: 30
Using renderer: AMD Radeon Graphics (radeonsi, renoir, LLVM 19.1.3, DRM 3.59, 6.11.4-amd64)
Found discrete GPU, setting DRI_PRIME=1 to use it.
Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
ERROR: Condition "ctxErrorOccurred || !gl_display.context->glx_context" is true. Returning: ERR_UNCONFIGURED
   at: _create_context (platform/linuxbsd/x11/gl_manager_x11.cpp:183)
WARNING: Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES.
     at: DisplayServerX11 (platform/linuxbsd/x11/display_server_x11.cpp:6232)
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
Loaded EGL 1.5
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
ERROR: Can't create an EGL context. Error code: 12291
   at: _gldisplay_create_context (drivers/egl/egl_manager.cpp:196)
ERROR: Method/function failed. Returning: -1
   at: _get_gldisplay_id (drivers/egl/egl_manager.cpp:104)
ERROR: Condition "gldisplay_id < 0" is true. Returning: ERR_CANT_CREATE
   at: display_get_native_visual_id (drivers/egl/egl_manager.cpp:212)
ERROR: Condition "number_of_visuals <= 0" is true. Returning: INVALID_WINDOW_ID
   at: _create_window (platform/linuxbsd/x11/display_server_x11.cpp:5475)
Output 7f0f280035d0 done.
Output 7f0f280035d0 scale 1
Output 7f0f280037e0 scale 1
Output 7f0f280037e0 done.
Loading cursor theme "Adwaita" size 24.
Failed loading cursor: crossed_circle
libspeechd.so.2: cannot open shared object file: No such file or directory
Text-to-Speech: Cannot load Speech Dispatcher library!
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
Loaded EGL 1.5
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
ERROR: Can't create an EGL context. Error code: 12291
   at: _gldisplay_create_context (drivers/egl/egl_manager.cpp:196)
ERROR: Method/function failed. Returning: -1
   at: _get_gldisplay_id (drivers/egl/egl_manager.cpp:104)
WARNING: Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES.
     at: DisplayServerWayland (platform/linuxbsd/wayland/display_server_wayland.cpp:1430)
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
Loaded EGL 1.5
Showing window.
Window has no output associated, returning buffer scale of 1.
libdecor frame on configure rect [P: (0, 0), S: (1280, 720)]
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
radeonsi: can't create eop_bug_scratch
radeonsi: Failed to create a context.
ERROR: Can't create an EGL context. Error code: 12291
   at: _gldisplay_create_context (drivers/egl/egl_manager.cpp:196)
ERROR: Method/function failed. Returning: -1
   at: _get_gldisplay_id (drivers/egl/egl_manager.cpp:104)
ERROR: Condition "gldisplay_id < 0" is true. Returning: ERR_CANT_CREATE
   at: window_create (drivers/egl/egl_manager.cpp:227)
ERROR: Can't show a GLES3 window.
   at: _show_window (platform/linuxbsd/wayland/display_server_wayland.cpp:178)
PortalDesktop: DBus 1.14.10 detected.
ScreenSaver: DBus 1.14.10 detected.
Using "default" pen tablet driver...
ERROR: Error initializing GLAD.
   at: RasterizerGLES3 (drivers/gles3/rasterizer_gles3.cpp:270)

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.3.stable.official (77dcf97d82cbfe4e4615475fa52ca03da645dbd8)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /lib/x86_64-linux-gnu/libc.so.6(+0x3fd20) [0x7f101ac95d20] (??:0)
[2] ../Godot_v4.3-stable_linux.x86_64() [0x384d6db] (??:0)
[3] ../Godot_v4.3-stable_linux.x86_64() [0x118bd95] (??:0)
[4] ../Godot_v4.3-stable_linux.x86_64() [0x3888855] (??:0)
[5] ../Godot_v4.3-stable_linux.x86_64() [0x47bc47b] (??:0)
[6] ../Godot_v4.3-stable_linux.x86_64() [0x4718aa2] (??:0)
[7] ../Godot_v4.3-stable_linux.x86_64() [0x4200b5] (??:0)
[8] /lib/x86_64-linux-gnu/libc.so.6(+0x29d68) [0x7f101ac7fd68] (??:0)
[9] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85) [0x7f101ac7fe25] (??:0)
[10] ../Godot_v4.3-stable_linux.x86_64() [0x43d44a] (??:0)
-- END OF BACKTRACE --
================================================================

Minimal reproduction project (MRP)

I've only tested with a single project but I'm sure this would occur on any project.

akien-mga commented 2 days ago

There's currently no way to override this behaviour.

There might be actually.

You can try to run Godot with DRI_PRIME=0. It sounds like on your system the Intel GPU is DRI_PRIME=0 while the AMD one is DRI_PRIME=1, which is counter to the usual "0 is integrated, 1 is discrete" understanding of this setting. If that doesn't work, I think DRI_PRIME also supports passing the full PCI ID as an argument.

Another option is to force using Vulkan instead of OpenGL (GL is the default for the project manager), by running Godot with --rendering-driver vulkan. When using Vulkan, you can then further specify which GPU to use with --gpu-index <number>, and that number should be the GPU id you can find with vulkaninfo, or running Godot with --rendering-driver vulkan --verbose, which should print "Devices:" with a list of supported devices.


As for the problem, the Linux platform when using OpenGL has some heuristics in the detect_prime method to find out what GPUs are available and rate their likely "priority" for gaming purposes. Up until now a setup with an Intel discrete GPU that's more powerful/relevant than an integrated GPU was unheard of, so this code systematically rates Intel lower than AMD and Nvidia. Sounds like this needs to be reviewed.

https://github.com/godotengine/godot/blob/master/platform/linuxbsd/x11/detect_prime_x11.cpp#L68-L78

bl4ckb0ne commented 2 days ago

DRI_PRIME=0 helped, but I get an error in a shader now, seems unrelated to this and more related to XR since this is an XR project.

--rendering-driver vulkan renders something! It looks like it picks the Intel GPU by default. without requiring the gpu index.

The heuristic for OpenGL could definitely use an upgrade indeed.

Thanks for your quick answer