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.

@@ -1276,7 +1274,7 @@

6.3.1 Sanity Check

execute the following command in the SSH session:

-/opt/VirtualGL/bin/eglinfo /dev/dri/card0
+/opt/VirtualGL/bin/eglinfo egl0
 

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

- + @@ -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");
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