summaryrefslogtreecommitdiff
path: root/src/intel_device.c
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 /src/intel_device.c
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>
Diffstat (limited to 'src/intel_device.c')
-rw-r--r--src/intel_device.c54
1 files changed, 47 insertions, 7 deletions
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);
}