From: Pierre Ossman Date: Thu, 6 Jun 2024 12:51:52 +0000 (+0200) Subject: Automatically pick a suitable DRI3 render node X-Git-Tag: v1.13.90~2^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b0d6b1408c0e98c8e2d1dfe1c463c6e575cdf769;p=tigervnc.git Automatically pick a suitable DRI3 render node Lay the groundwork for a more intelligent selection of GPU in systems that have multiple cards. This initial implementation simply picks the first GPU that we have permission to open. --- 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 #include +#include #include #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) {