diff options
-rw-r--r-- | unix/xserver/hw/vnc/Xvnc.man | 3 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncDRI3.c | 38 |
2 files changed, 37 insertions, 4 deletions
diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man index 05d34e81..fadf9d20 100644 --- a/unix/xserver/hw/vnc/Xvnc.man +++ b/unix/xserver/hw/vnc/Xvnc.man @@ -48,7 +48,8 @@ depth 16 is RGB565 and for depth 24 and 32 is RGB888. .TP .B \-rendernode \fIpath\fP DRM render node to use for DRI3 GPU acceleration. Specify an empty path to -disable DRI3. Default is /dev/dri/renderD128. +disable DRI3. Default is \fBauto\fP which makes \fBXvnc\fP pick a suitable +available render node. . .TP .B \-interface \fIIP address\fP diff --git a/unix/xserver/hw/vnc/vncDRI3.c b/unix/xserver/hw/vnc/vncDRI3.c index 1e643ece..79b56f10 100644 --- a/unix/xserver/hw/vnc/vncDRI3.c +++ b/unix/xserver/hw/vnc/vncDRI3.c @@ -22,6 +22,7 @@ #include <errno.h> #include <fcntl.h> +#include <glob.h> #include <unistd.h> #ifdef HAVE_GBM @@ -37,7 +38,7 @@ #error "This code is not compatible with accessors" #endif -const char *renderNode = "/dev/dri/renderD128"; +const char *renderNode = "auto"; static DevPrivateKeyRec vncDRI3ScreenPrivateKey; static DevPrivateKeyRec vncDRI3PixmapPrivateKey; @@ -458,7 +459,8 @@ Bool vncDRI3Init(ScreenPtr screen) if (renderNode[0] == '\0') return TRUE; - if (renderNode[0] != '/') { + if ((renderNode[0] != '/') && + (strcasecmp(renderNode, "auto") != 0)) { ErrorF("Invalid render node path \"%s\"\n", renderNode); return FALSE; } @@ -476,7 +478,37 @@ Bool vncDRI3Init(ScreenPtr screen) #ifdef HAVE_GBM screenPriv = vncDRI3ScreenPrivate(screen); - screenPriv->devicePath = renderNode; + if (strcasecmp(renderNode, "auto") == 0) { + glob_t globbuf; + int ret; + + ret = glob("/dev/dri/renderD*", 0, NULL, &globbuf); + if (ret == GLOB_NOMATCH) { + ErrorF("Could not find any render nodes\n"); + return FALSE; + } + if (ret != 0) { + ErrorF("Failure enumerating render nodes\n"); + return FALSE; + } + + screenPriv->devicePath = NULL; + for (size_t i = 0;i < globbuf.gl_pathc;i++) { + if (access(globbuf.gl_pathv[i], R_OK|W_OK) == 0) { + screenPriv->devicePath = strdup(globbuf.gl_pathv[i]); + break; + } + } + + globfree(&globbuf); + + if (screenPriv->devicePath == NULL) { + ErrorF("Could not find any available render nodes\n"); + return FALSE; + } + } else { + screenPriv->devicePath = renderNode; + } screenPriv->fd = open(screenPriv->devicePath, O_RDWR|O_CLOEXEC); if (screenPriv->fd < 0) { |