diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-23 18:53:34 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-23 19:27:23 +0100 |
commit | 8b0d69e76c50155ea404f0e8a97d60a3f710c8a3 (patch) | |
tree | d13540a452d224388c797fe5156e1d26f7b46c82 /src/intel_device.c | |
parent | 846436c1a26b2c8a9d787ec707edb075fac57ee0 (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.c | 54 |
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); } |