aboutsummaryrefslogtreecommitdiffstats
path: root/unix/xserver/hw
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2024-06-06 14:51:52 +0200
committerPierre Ossman <ossman@cendio.se>2024-06-20 14:41:48 +0200
commitb0d6b1408c0e98c8e2d1dfe1c463c6e575cdf769 (patch)
tree8ea660a9c328deacd802988495f3b17e3b7678a7 /unix/xserver/hw
parent9797511ff40f45e1125728828051610f0150d432 (diff)
downloadtigervnc-b0d6b1408c0e98c8e2d1dfe1c463c6e575cdf769.tar.gz
tigervnc-b0d6b1408c0e98c8e2d1dfe1c463c6e575cdf769.zip
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.
Diffstat (limited to 'unix/xserver/hw')
-rw-r--r--unix/xserver/hw/vnc/Xvnc.man3
-rw-r--r--unix/xserver/hw/vnc/vncDRI3.c38
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) {