egl: Add egl-device-index config var for selecting EGL device

Fixes #1306
This commit is contained in:
rdb 2022-05-17 11:52:19 +02:00
parent b5d615b223
commit 29c25a541c

View File

@ -21,6 +21,12 @@
#include <EGL/eglext.h> #include <EGL/eglext.h>
static ConfigVariableInt egl_device_index
("egl-device-index", -1,
PRC_DESC("Selects which EGL device index is used to create the EGL display in "
"a headless configuration. The special value -1 selects the default "
"device."));
TypeHandle eglGraphicsPipe::_type_handle; TypeHandle eglGraphicsPipe::_type_handle;
/** /**
@ -30,6 +36,8 @@ eglGraphicsPipe::
eglGraphicsPipe() { eglGraphicsPipe() {
// Check for client extensions. // Check for client extensions.
vector_string extensions; vector_string extensions;
bool supports_platform_device = false;
bool supports_device_enumeration = false;
const char *ext_ptr = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); const char *ext_ptr = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (ext_ptr != nullptr) { if (ext_ptr != nullptr) {
extract_words(ext_ptr, extensions); extract_words(ext_ptr, extensions);
@ -42,6 +50,13 @@ eglGraphicsPipe() {
out << " " << extension << "\n"; out << " " << extension << "\n";
} }
} }
if (std::find(extensions.begin(), extensions.end(), "EGL_EXT_platform_device") != extensions.end()) {
supports_platform_device = true;
}
if (std::find(extensions.begin(), extensions.end(), "EGL_EXT_device_enumeration") != extensions.end()) {
supports_device_enumeration = true;
}
} }
else if (egldisplay_cat.is_debug()) { else if (egldisplay_cat.is_debug()) {
eglGetError(); eglGetError();
@ -51,6 +66,46 @@ eglGraphicsPipe() {
EGLint major, minor; EGLint major, minor;
int index = egl_device_index.get_value();
if (index >= 0 && supports_platform_device && supports_device_enumeration) {
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
EGLint num_devices = 0;
if (eglQueryDevicesEXT != nullptr &&
eglQueryDevicesEXT(0, nullptr, &num_devices) &&
num_devices > 0) {
EGLDeviceEXT *devices = (EGLDeviceEXT *)alloca(sizeof(EGLDeviceEXT) * num_devices);
eglQueryDevicesEXT(num_devices, devices, &num_devices);
if (index >= num_devices) {
egldisplay_cat.error()
<< "Requested EGL device index " << index << " does not exist ("
<< "there are only " << num_devices << " devices)\n";
_is_valid = false;
return;
}
if (egldisplay_cat.is_debug()) {
egldisplay_cat.debug()
<< "Found " << num_devices << " EGL devices, using device index "
<< index << ".\n";
}
_egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[index], nullptr);
if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) {
egldisplay_cat.error()
<< "Couldn't initialize EGL platform display " << index << ": "
<< get_egl_error_string(eglGetError()) << "\n";
_egl_display = EGL_NO_DISPLAY;
}
}
}
else {
//NB. if the X11 display failed to open, _display will be 0, which is a valid //NB. if the X11 display failed to open, _display will be 0, which is a valid
// input to eglGetDisplay - it means to open the default display. // input to eglGetDisplay - it means to open the default display.
#ifdef USE_X11 #ifdef USE_X11
@ -65,10 +120,7 @@ eglGraphicsPipe() {
_egl_display = EGL_NO_DISPLAY; _egl_display = EGL_NO_DISPLAY;
} }
if (!_egl_display && if (!_egl_display && supports_platform_device && supports_device_enumeration) {
std::find(extensions.begin(), extensions.end(), "EGL_EXT_platform_device") != extensions.end() &&
std::find(extensions.begin(), extensions.end(), "EGL_EXT_device_enumeration") != extensions.end()) {
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT"); (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
@ -101,6 +153,7 @@ eglGraphicsPipe() {
} }
} }
} }
}
if (!_egl_display) { if (!_egl_display) {
egldisplay_cat.error() egldisplay_cat.error()