From 8b0d69e76c50155ea404f0e8a97d60a3f710c8a3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 23 Aug 2013 18:53:34 +0100 Subject: 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 --- src/intel_device.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 7 deletions(-) (limited to 'src/intel_device.c') 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 +#include #include #include #include @@ -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); } -- cgit v1.2.3