summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-23 18:53:34 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-23 19:27:23 +0100
commit8b0d69e76c50155ea404f0e8a97d60a3f710c8a3 (patch)
treed13540a452d224388c797fe5156e1d26f7b46c82
parent846436c1a26b2c8a9d787ec707edb075fac57ee0 (diff)
intel: Add experimental rendernode support
Render nodes allow clients full access to off-screen rendering and GPU offload, without assuming any master responsiblities (for device and display management). As they have a more limited interface, they can be used in a more permissive manner. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--configure.ac11
-rw-r--r--src/intel_device.c54
-rw-r--r--src/intel_driver.h2
-rw-r--r--src/sna/sna_dri.c2
4 files changed, 60 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac
index 9fc011ec..1e73c0c1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -336,6 +336,17 @@ fi
xp_msg=""
+AC_ARG_ENABLE(rendernode,
+ AS_HELP_STRING([--enable-rendernode],
+ [Enable use of render nodes (experimental) [default=no]]),
+ [RENDERNODE="$enableval"],
+ [RENDERNODE=no])
+AM_CONDITIONAL(USE_RENDERNODE, test x$RENDERNODE = xyes)
+if test "x$RENDERNODE" = xyes; then
+ AC_DEFINE(USE_RENDERNODE,1,[Assume "rendernode" support])
+ xp_msg="$xp_msg rendernode"
+fi
+
AC_ARG_ENABLE(create2,
AS_HELP_STRING([--enable-create2],
[Enable use of create2 ioctl (experimental) [default=no]]),
diff --git a/src/intel_device.c b/src/intel_device.c
index d9ff8bcc..751875e3 100644
--- a/src/intel_device.c
+++ b/src/intel_device.c
@@ -24,6 +24,12 @@
**************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
@@ -43,7 +49,8 @@
#include "intel_driver.h"
struct intel_device {
- char *path;
+ char *master_node;
+ char *render_node;
int fd;
int open_count;
int master_count;
@@ -164,6 +171,32 @@ static int __intel_open_device(const struct pci_device *pci, char **path)
return fd;
}
+static char *find_render_node(int fd)
+{
+#if defined(USE_RENDERNODE)
+ struct stat master, render;
+ char buf[128];
+
+ if (fstat(fd, &master))
+ return NULL;
+
+ if (!S_ISCHR(master.st_mode))
+ return NULL;
+
+ /* Are we a render-node ourselves? */
+ if (master.st_rdev & 0x80)
+ return NULL;
+
+ sprintf(buf, "/dev/dri/renderD%d", (int)((master.st_rdev | 0x80) & 0xff));
+ if (stat(buf, &render) == 0 &&
+ master.st_mode == render.st_mode &&
+ render.st_rdev == (master.st_rdev | 0x80))
+ return strdup(buf);
+#endif
+
+ return NULL;
+}
+
int intel_open_device(int entity_num,
const struct pci_device *pci,
const char *path)
@@ -194,10 +227,13 @@ int intel_open_device(int entity_num,
if (dev == NULL)
goto err_close;
- dev->path = local_path;
dev->fd = fd;
dev->open_count = 0;
dev->master_count = 0;
+ dev->master_node = local_path;
+ dev->render_node = find_render_node(fd);
+ if (dev->render_node == NULL)
+ dev->render_node = dev->master_node;
/* If hosted under a system compositor, just pretend to be master */
if (hosted()) {
@@ -257,11 +293,11 @@ int intel_get_device(ScrnInfoPtr scrn)
return dev->fd;
}
-const char *intel_get_device_name(ScrnInfoPtr scrn)
+const char *intel_get_client_name(ScrnInfoPtr scrn)
{
struct intel_device *dev = intel_device(scrn);
- assert(dev && dev->path);
- return dev->path;
+ assert(dev && dev->render_node);
+ return dev->render_node;
}
int intel_get_master(ScrnInfoPtr scrn)
@@ -312,7 +348,9 @@ void __intel_uxa_release_device(ScrnInfoPtr scrn)
intel_set_device(scrn, NULL);
drmClose(dev->fd);
- free(dev->path);
+ if (dev->render_node != dev->master_node)
+ free(dev->render_node);
+ free(dev->master_node);
free(dev);
}
}
@@ -331,6 +369,8 @@ void intel_put_device(ScrnInfoPtr scrn)
intel_set_device(scrn, NULL);
drmClose(dev->fd);
- free(dev->path);
+ if (dev->render_node != dev->master_node)
+ free(dev->render_node);
+ free(dev->master_node);
free(dev);
}
diff --git a/src/intel_driver.h b/src/intel_driver.h
index 47685364..e54054fe 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -122,7 +122,7 @@ void intel_detect_chipset(ScrnInfoPtr scrn,
int intel_open_device(int entity_num, const struct pci_device *pci, const char *path);
int intel_get_device(ScrnInfoPtr scrn);
-const char *intel_get_device_name(ScrnInfoPtr scrn);
+const char *intel_get_client_name(ScrnInfoPtr scrn);
int intel_get_master(ScrnInfoPtr scrn);
int intel_put_master(ScrnInfoPtr scrn);
void intel_put_device(ScrnInfoPtr scrn);
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index ff960759..f31ca4e9 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -2321,7 +2321,7 @@ bool sna_dri_open(struct sna *sna, ScreenPtr screen)
memset(&info, '\0', sizeof(info));
info.fd = sna->kgem.fd;
info.driverName = dri_driver_name(sna);
- info.deviceName = intel_get_device_name(sna->scrn);
+ info.deviceName = intel_get_client_name(sna->scrn);
DBG(("%s: loading dri driver '%s' [gen=%d] for device '%s'\n",
__FUNCTION__, info.driverName, sna->kgem.gen, info.deviceName));