Properly detect when to use DRI_PRIME

We fork off twice once with and once without DIR_PRIME=1 set. We
then use the vendor string to determine what GPU to use.

We prefer (in order)
1) AMDGPU/AMDGPU-PRO/NVidia non-free driver
2) Intel driver
3) Nouveau
4) Software rendering

If a driver can't be detected it will default to DRI_PRIME=0
This commit is contained in:
Hein-Pieter van Braam
2019-01-27 22:31:38 +00:00
parent 59459ed4b2
commit 9c308023bb
4 changed files with 280 additions and 20 deletions

View File

@ -29,6 +29,8 @@
/*************************************************************************/
#include "os_x11.h"
#include "detect_prime.h"
#include "core/os/dir_access.h"
#include "core/print_string.h"
#include "drivers/gles2/rasterizer_gles2.h"
@ -240,28 +242,15 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
// maybe contextgl wants to be in charge of creating the window
#if defined(OPENGL_ENABLED)
// Set DRI_PRIME if not set. This means that Godot should default to a higher-power GPU if it exists.
// Note: Due to the final '0' parameter to setenv any existing DRI_PRIME environment variables will not
// be overwritten.
bool enable_dri_prime = true;
// Check if Nouveau is loaded, we don't want to force dGPU usage with that driver.
if (FileAccess *f = FileAccess::open("/proc/modules", FileAccess::READ)) {
// Match driver name + space
String nouveau_str = "nouveau ";
if (getenv("DRI_PRIME") == NULL) {
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
int use_prime = detect_prime();
while (!f->eof_reached()) {
String line = f->get_line();
if (line.begins_with(nouveau_str)) {
enable_dri_prime = false;
break;
}
if (use_prime) {
print_line("Found discrete GPU, setting DRI_PRIME=1 to use it.");
print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
setenv("DRI_PRIME", "1", 1);
}
f->close();
memdelete(f);
}
if (enable_dri_prime) {
setenv("DRI_PRIME", "1", 0);
}
ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_3_0_COMPATIBLE;