|
@@ -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,23 +66,10 @@ eglGraphicsPipe() {
|
|
|
|
|
|
|
|
EGLint major, minor;
|
|
EGLint major, minor;
|
|
|
|
|
|
|
|
- //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.
|
|
|
|
|
-#ifdef USE_X11
|
|
|
|
|
- _egl_display = eglGetDisplay((NativeDisplayType) _display);
|
|
|
|
|
-#else
|
|
|
|
|
- _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
|
|
|
|
-#endif
|
|
|
|
|
- if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) {
|
|
|
|
|
- egldisplay_cat.warning()
|
|
|
|
|
- << "Couldn't initialize the default EGL display: "
|
|
|
|
|
- << get_egl_error_string(eglGetError()) << "\n";
|
|
|
|
|
- _egl_display = EGL_NO_DISPLAY;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!_egl_display &&
|
|
|
|
|
- std::find(extensions.begin(), extensions.end(), "EGL_EXT_platform_device") != extensions.end() &&
|
|
|
|
|
- std::find(extensions.begin(), extensions.end(), "EGL_EXT_device_enumeration") != extensions.end()) {
|
|
|
|
|
|
|
+ int index = egl_device_index.get_value();
|
|
|
|
|
+ if (index >= 0 && supports_platform_device && supports_device_enumeration) {
|
|
|
|
|
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
|
|
|
|
|
+ (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
|
|
|
|
|
|
|
|
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
|
|
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
|
|
|
(PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
|
|
(PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
|
|
@@ -79,23 +81,74 @@ eglGraphicsPipe() {
|
|
|
EGLDeviceEXT *devices = (EGLDeviceEXT *)alloca(sizeof(EGLDeviceEXT) * num_devices);
|
|
EGLDeviceEXT *devices = (EGLDeviceEXT *)alloca(sizeof(EGLDeviceEXT) * num_devices);
|
|
|
eglQueryDevicesEXT(num_devices, devices, &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()) {
|
|
if (egldisplay_cat.is_debug()) {
|
|
|
egldisplay_cat.debug()
|
|
egldisplay_cat.debug()
|
|
|
- << "Found " << num_devices << " EGL devices.\n";
|
|
|
|
|
|
|
+ << "Found " << num_devices << " EGL devices, using device index "
|
|
|
|
|
+ << index << ".\n";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
|
|
|
|
|
- (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
|
|
|
|
|
|
|
+ _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
|
|
|
|
|
+ // input to eglGetDisplay - it means to open the default display.
|
|
|
|
|
+ #ifdef USE_X11
|
|
|
|
|
+ _egl_display = eglGetDisplay((NativeDisplayType) _display);
|
|
|
|
|
+ #else
|
|
|
|
|
+ _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
|
|
|
|
+ #endif
|
|
|
|
|
+ if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) {
|
|
|
|
|
+ egldisplay_cat.warning()
|
|
|
|
|
+ << "Couldn't initialize the default EGL display: "
|
|
|
|
|
+ << get_egl_error_string(eglGetError()) << "\n";
|
|
|
|
|
+ _egl_display = EGL_NO_DISPLAY;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!_egl_display && supports_platform_device && supports_device_enumeration) {
|
|
|
|
|
+ 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 (egldisplay_cat.is_debug()) {
|
|
|
|
|
+ egldisplay_cat.debug()
|
|
|
|
|
+ << "Found " << num_devices << " EGL devices.\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
|
|
|
|
|
+ (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
|
|
|
|
|
|
|
|
- if (eglGetPlatformDisplayEXT != nullptr) {
|
|
|
|
|
- for (EGLint i = 0; i < num_devices && !_egl_display; ++i) {
|
|
|
|
|
- _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i], nullptr);
|
|
|
|
|
|
|
+ if (eglGetPlatformDisplayEXT != nullptr) {
|
|
|
|
|
+ for (EGLint i = 0; i < num_devices && !_egl_display; ++i) {
|
|
|
|
|
+ _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i], nullptr);
|
|
|
|
|
|
|
|
- if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) {
|
|
|
|
|
- egldisplay_cat.warning()
|
|
|
|
|
- << "Couldn't initialize EGL platform display " << i << ": "
|
|
|
|
|
- << get_egl_error_string(eglGetError()) << "\n";
|
|
|
|
|
- _egl_display = EGL_NO_DISPLAY;
|
|
|
|
|
|
|
+ if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) {
|
|
|
|
|
+ egldisplay_cat.warning()
|
|
|
|
|
+ << "Couldn't initialize EGL platform display " << i << ": "
|
|
|
|
|
+ << get_egl_error_string(eglGetError()) << "\n";
|
|
|
|
|
+ _egl_display = EGL_NO_DISPLAY;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|