diff --git a/ChangeLog.md b/ChangeLog.md
index 4b9cc36f..dd3db983 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -10,6 +10,11 @@ display manager was restarted.
2. Fixed compilation errors when building with libX11 1.8.x.
+3. When using the EGL back end, a GPU can now be specified by an EGL device ID
+of the form `egl{n}`, where `{n}` is a zero-based index, or by a DRI device
+path. A list of valid EGL device IDs and their associated DRI device paths can
+be obtained by running `/opt/VirtualGL/bin/eglinfo -e`.
+
3.0.1
=====
diff --git a/demos/eglinfo.c b/demos/eglinfo.c
index 087238cd..c4a7dedd 100644
--- a/demos/eglinfo.c
+++ b/demos/eglinfo.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2014 Brian Paul All Rights Reserved.
* Copyright (C) 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (C) 2011, 2013, 2015, 2019-2021 D. R. Commander
+ * Copyright (C) 2011, 2013, 2015, 2019-2022 D. R. Commander
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -242,7 +242,7 @@ create_context_with_config(EGLDisplay edpy, EGLConfig config,
static GLboolean
print_display_info(EGLDisplay edpy,
- const struct options *opts,
+ const struct options *opts, int eglDeviceID,
GLboolean coreProfile, GLboolean limits,
GLboolean coreWorked)
{
@@ -315,7 +315,12 @@ print_display_info(EGLDisplay edpy,
CheckError(__LINE__);
if (!coreWorked) {
- printf("device: %s\n", opts->displayName);
+ printf("EGL device ID: egl%d", eglDeviceID);
+ if (eglDeviceID == 0)
+ printf(" or egl");
+ printf("\n");
+ if (opts->displayName)
+ printf("DRI device path: %s\n", opts->displayName);
if (opts->mode != Brief) {
printf("EGL client APIs string: %s\n", eglAPIs);
printf("EGL vendor string: %s\n", eglVendor);
@@ -610,8 +615,9 @@ static void
usage(void)
{
printf("Usage: eglinfo [-v] [-h] [-l] [-s]\n");
- printf("\t: Print EGL configs for the specified DRI device.\n");
- printf("\t (\"egl\" = print EGL configs for the first DRI device)\n");
+ printf("\t: Print EGL configs for the specified EGL device. can\n");
+ printf("\t be a DRI device path or an EGL device ID (use -e for a list.)\n");
+ printf("\t-e: List all valid EGL devices\n");
printf("\t-B: brief output, print only the basics.\n");
printf("\t-v: Print config info in verbose form.\n");
printf("\t-h: This information.\n");
@@ -623,8 +629,8 @@ usage(void)
int
main(int argc, char *argv[])
{
- const char *exts;
- int numDevices, major, minor, i;
+ const char *exts, *devStr = NULL;
+ int numDevices, major, minor, i, list = 0, validDevices = 0;
EGLDeviceEXT *devices = NULL;
EGLDisplay edpy;
struct options opts;
@@ -660,11 +666,14 @@ main(int argc, char *argv[])
else if (strcmp(argv[i], "-s") == 0) {
opts.singleLine = GL_TRUE;
}
+ else if (strcmp(argv[i], "-e") == 0) {
+ list = 1;
+ }
else {
opts.displayName = argv[i];
}
}
- if (!opts.displayName) {
+ if (!opts.displayName && !list) {
usage();
exit(0);
}
@@ -712,18 +721,38 @@ main(int argc, char *argv[])
return -1;
}
for (i = 0; i < numDevices; i++) {
- const char *devStr;
-
edpy = _eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i],
NULL);
if (!edpy || !eglInitialize(edpy, &major, &minor))
continue;
eglTerminate(edpy);
- if (!strcasecmp(opts.displayName, "egl"))
- break;
devStr = _eglQueryDeviceStringEXT(devices[i], EGL_DRM_DEVICE_FILE_EXT);
- if (devStr && !strcmp(devStr, opts.displayName))
- break;
+ if (opts.displayName && !list) {
+ if (!strcasecmp(opts.displayName, "egl"))
+ break;
+ if (!strncasecmp(opts.displayName, "egl", 3)) {
+ char temps[80];
+
+ snprintf(temps, 80, "egl%d", validDevices);
+ if (!strcasecmp(opts.displayName, temps))
+ break;
+ }
+ if (devStr && !strcmp(devStr, opts.displayName))
+ break;
+ }
+ if (list) {
+ printf("EGL device ID: egl%d", validDevices);
+ if (validDevices == 0)
+ printf(" or egl");
+ if (devStr)
+ printf(", DRI device path: %s", devStr);
+ printf("\n");
+ }
+ validDevices++;
+ }
+ if (list) {
+ free(devices);
+ return 0;
}
if (i == numDevices) {
fprintf(stderr, "Error: invalid EGL device\n");
@@ -742,9 +771,11 @@ main(int argc, char *argv[])
return -1;
}
- coreWorked = print_display_info(edpy, &opts, GL_TRUE, opts.limits,
- GL_FALSE);
- print_display_info(edpy, &opts, GL_FALSE, opts.limits, coreWorked);
+ opts.displayName = (char *)devStr;
+ coreWorked = print_display_info(edpy, &opts, validDevices, GL_TRUE,
+ opts.limits, GL_FALSE);
+ print_display_info(edpy, &opts, validDevices, GL_FALSE, opts.limits,
+ coreWorked);
printf("\n");
diff --git a/doc/advancedconfig.txt b/doc/advancedconfig.txt
index 4eb09f24..38bd111f 100644
--- a/doc/advancedconfig.txt
+++ b/doc/advancedconfig.txt
@@ -113,9 +113,10 @@ previous method:
''VGL_COMPRESS'' to any numeric value >= 0 (Default value = ''0''.) The
plugin can choose to respond to this value as it sees fit.
+{anchor: VGL_DISPLAY}
| Environment Variable | {pcode: VGL_DISPLAY = __{d}__ } |
| ''vglrun'' argument | {pcode: -d __{d}__ } |
-| Summary | __''{d}''__ = the X display/screen or DRI device to use for 3D \
+| Summary | __''{d}''__ = the X display/screen or EGL device to use for 3D \
rendering |
| Image Transports | All |
| Default Value | '':0'' |
@@ -127,9 +128,11 @@ previous method:
'':0.1'' would cause VirtualGL to use the GLX back end and redirect all of
the OpenGL rendering from the 3D application to a GPU attached to Screen 1 on
X display :0. Setting ''VGL_DISPLAY'' to (or invoking ''vglrun -d'' with)
- ''/dev/dri/card0'' or ''egl'' would cause VirtualGL to use the EGL back end
- and redirect all of the OpenGL rendering from the 3D application to the first
- GPU in the system.
+ a DRI device path (such as ''/dev/dri/card0'') or an EGL device ID (such as
+ ''egl0'') would cause VirtualGL to use the EGL back end and redirect all of
+ the OpenGL rendering from the 3D application to the specified EGL device.
+ ''/opt/VirtualGL/bin/eglinfo -e'' lists all valid EGL device IDs and their
+ associated DRI device paths.
| Environment Variable | {pcode: VGL_EGLLIB = __{l}__ } |
| Summary | __''{l}''__ = the location of an alternate EGL library |
diff --git a/doc/index.html b/doc/index.html
index 8f94ace5..f3725eb4 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -3,7 +3,7 @@
-
+
User’s Guide for VirtualGL 3.0.2
@@ -369,7 +369,7 @@
2.1 Terminology
API, so it can only access a GPU through an attached X server (the 3D X
server.) The EGL back end uses the EGL API with the
EGL_EXT_platform_device extension, so it accesses a GPU
- through an associated DRI device without the need for a 3D X server.
+ through an associated EGL device without the need for a 3D X server.
The EGL back end emulates a subset of the GLX API using the EGL API.
Since the EGL API does not support multi-buffering (double buffering or
quad-buffered stereo) with off-screen surfaces, the EGL back end
@@ -469,15 +469,14 @@
3 Overview
delivery of X11 2D drawing commands to the X server. For the most part,
VGL does not interfere with the delivery of OpenGL commands to the GPU,
either. VGL merely forces the OpenGL commands to be delivered to a GPU
-in the application server, either through the 3D X server attached to
-the GPU or through a DRI device, rather than to the X server to which
-the 2D drawing commands are delivered (the 2D X server.) Once the
-OpenGL rendering has been redirected to an off-screen buffer, everything
-(including esoteric OpenGL extensions, fragment/vertex shaders, etc.)
-should “just work.” If an OpenGL application runs correctly
-when accessing a 3D server/workstation locally, then the same
-application should run correctly with VirtualGL when accessing the same
-machine remotely.
+in the application server (through the 3D X server or EGL device
+attached to the GPU) rather than to the X server to which the 2D drawing
+commands are delivered (the 2D X server.) Once the OpenGL rendering has
+been redirected to an off-screen buffer, everything (including esoteric
+OpenGL extensions, fragment/vertex shaders, etc.) should “just
+work.” If an OpenGL application runs correctly when accessing a
+3D server/workstation locally, then the same application should run
+correctly with VirtualGL when accessing the same machine remotely.
VirtualGL has two built-in “image transports” that can be
used to deliver rendered frames to the 2D X server:
@@ -1206,10 +1205,9 @@
6.2.1 Sanity Check
6.3 EGL Back End: Granting Access to the GPU(s)
-
When using the EGL back end, accessing a GPU requires going through an
-associated DRI device, so the only way to share the application
+
When using the EGL back end, the only way to share the application
server’s GPU(s) among multiple users is to grant those users
-access to the DRI device(s) associated with the GPU(s).
+access to the device(s) associated with the GPU(s).
This section will explain how to configure a VirtualGL server such that
selected users can use the EGL back end.
This command should output a list of EGL configs and should complete
@@ -1299,11 +1297,12 @@
6.4 Using VirtualGL with Multiple GPUs
with) :0.0, :1.0, :2.0, etc.
Setting VGL_DISPLAY to (or invoking
-vglrun -d with) egl or the path to a DRI
-device enables the EGL back end. When using the EGL back end, a
-specific GPU can be selected by setting VGL_DISPLAY to (or
-invoking vglrun -d with) /dev/dri/card0,
-/dev/dri/card1, /dev/dri/card2, etc.
+vglrun -d with) a DRI device path
+(/dev/dri/card0, /dev/dri/card1,
+/dev/dri/card2, etc.) or an EGL device ID
+(egl0, egl1, egl2, etc.) enables
+the EGL back end and selects the specified GPU. See Section
+19.1 for more details.
@@ -3097,6 +3096,8 @@
19.1 Faker Settings
+
+
@@ -3109,7 +3110,7 @@
19.1 Faker Settings
Summary
-
{d} = the X display/screen or DRI device to use for 3D rendering
+
{d} = the X display/screen or EGL device to use for 3D rendering
Image Transports
@@ -3133,10 +3134,12 @@
19.1 Faker Settings
VirtualGL to use the GLX back end and redirect all of the OpenGL
rendering from the 3D application to a GPU attached to Screen 1 on X
display :0. Setting VGL_DISPLAY to (or invoking
- vglrun -d with) /dev/dri/card0 or
- egl would cause VirtualGL to use the EGL back end and
+ vglrun -d with) a DRI device path (such as
+ /dev/dri/card0) or an EGL device ID (such as
+ egl0) would cause VirtualGL to use the EGL back end and
redirect all of the OpenGL rendering from the 3D application to the
- first GPU in the system.
+ specified EGL device. /opt/VirtualGL/bin/eglinfo -e
+ lists all valid EGL device IDs and their associated DRI device paths.
diff --git a/doc/overview.txt b/doc/overview.txt
index 89658176..99e4ecd4 100644
--- a/doc/overview.txt
+++ b/doc/overview.txt
@@ -47,14 +47,14 @@ X11 commands and events to determine when windows have been resized, etc., but
it does not interfere in any way with the delivery of X11 2D drawing commands
to the X server. For the most part, VGL does not interfere with the delivery
of OpenGL commands to the GPU, either. VGL merely forces the OpenGL commands
-to be delivered to a GPU in the application server, either through the 3D X
-server attached to the GPU or through a DRI device, rather than to the X server
-to which the 2D drawing commands are delivered (the 2D X server.) Once the
-OpenGL rendering has been redirected to an off-screen buffer, everything
-(including esoteric OpenGL extensions, fragment/vertex shaders, etc.) should
-"just work." If an OpenGL application runs correctly when accessing a 3D
-server/workstation locally, then the same application should run correctly with
-VirtualGL when accessing the same machine remotely.
+to be delivered to a GPU in the application server (through the 3D X server or
+EGL device attached to the GPU) rather than to the X server to which the 2D
+drawing commands are delivered (the 2D X server.) Once the OpenGL rendering
+has been redirected to an off-screen buffer, everything (including esoteric
+OpenGL extensions, fragment/vertex shaders, etc.) should "just work." If an
+OpenGL application runs correctly when accessing a 3D server/workstation
+locally, then the same application should run correctly with VirtualGL when
+accessing the same machine remotely.
VirtualGL has two built-in "image transports" that can be used to deliver
rendered frames to the 2D X server:
diff --git a/doc/prefix.txt b/doc/prefix.txt
index c9bb978f..f8302c71 100644
--- a/doc/prefix.txt
+++ b/doc/prefix.txt
@@ -51,7 +51,7 @@ different directory, then adjust the instructions accordingly.
the GLX API, so it can only access a GPU through an attached X server (the 3D
X server.) The EGL back end uses the EGL API with the
''EGL_EXT_platform_device'' extension, so it accesses a GPU through an
- associated DRI device without the need for a 3D X server. The EGL back end
+ associated EGL device without the need for a 3D X server. The EGL back end
emulates a subset of the GLX API using the EGL API. Since the EGL API does
not support multi-buffering (double buffering or quad-buffered stereo) with
off-screen surfaces, the EGL back end emulates multi-buffering using OpenGL
diff --git a/doc/unixconfig.txt b/doc/unixconfig.txt
index deda928e..1f6f0775 100644
--- a/doc/unixconfig.txt
+++ b/doc/unixconfig.txt
@@ -239,9 +239,8 @@ OpenGL renderer string.
** EGL Back End: Granting Access to the GPU(s)
-When using the EGL back end, accessing a GPU requires going through an
-associated DRI device, so the only way to share the application server's GPU(s)
-among multiple users is to grant those users access to the DRI device(s)
+When using the EGL back end, the only way to share the application server's
+GPU(s) among multiple users is to grant those users access to the device(s)
associated with the GPU(s).
This section will explain how to configure a VirtualGL server such that
@@ -292,7 +291,7 @@ end, log out of the server, log back into the server using SSH, and execute the
following command in the SSH session:
#Verb <<---
- /opt/VirtualGL/bin/eglinfo /dev/dri/card0
+ /opt/VirtualGL/bin/eglinfo egl0
---
This command should output a list of EGL configs and should complete with no
@@ -310,11 +309,11 @@ by setting ''VGL_DISPLAY'' to (or invoking ''vglrun -d'' with) '':0.0'',
a specific GPU can be selected by setting ''VGL_DISPLAY'' to (or invoking
''vglrun -d'' with) '':0.0'', '':1.0'', '':2.0'', etc.
-Setting ''VGL_DISPLAY'' to (or invoking ''vglrun -d'' with) ''egl'' or the path
-to a DRI device enables the EGL back end. When using the EGL back end, a
-specific GPU can be selected by setting ''VGL_DISPLAY'' to (or invoking
-''vglrun -d'' with) ''/dev/dri/card0'', ''/dev/dri/card1'', ''/dev/dri/card2'',
-etc.
+Setting ''VGL_DISPLAY'' to (or invoking ''vglrun -d'' with) a DRI device path
+(''/dev/dri/card0'', ''/dev/dri/card1'', ''/dev/dri/card2'', etc.) or an EGL
+device ID (''egl0'', ''egl1'', ''egl2'', etc.) enables the EGL back end and
+selects the specified GPU. See {ref prefix="Section ": VGL_DISPLAY} for more
+details.
** SSH Server Configuration
diff --git a/server/faker.cpp b/server/faker.cpp
index 601cfa3e..5b64aaef 100644
--- a/server/faker.cpp
+++ b/server/faker.cpp
@@ -177,7 +177,7 @@ Display *init3D(void)
#ifdef EGLBACKEND
if(fconfig.egl)
{
- int numDevices = 0, i;
+ int numDevices = 0, i, validDevices = 0;
const char *exts = NULL;
EGLDeviceEXT *devices = NULL;
@@ -211,10 +211,19 @@ Display *init3D(void)
_eglTerminate(edpy);
if(!strcasecmp(fconfig.localdpystring, "egl"))
break;
+ if(!strncasecmp(fconfig.localdpystring, "egl", 3))
+ {
+ char temps[80];
+
+ snprintf(temps, 80, "egl%d", validDevices);
+ if(!strcasecmp(fconfig.localdpystring, temps))
+ break;
+ }
const char *devStr =
_eglQueryDeviceStringEXT(devices[i], EGL_DRM_DEVICE_FILE_EXT);
if(devStr && !strcmp(devStr, fconfig.localdpystring))
break;
+ validDevices++;
}
if(i == numDevices) THROW("Invalid EGL device");