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 | |
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>
-rw-r--r-- | configure.ac | 11 | ||||
-rw-r--r-- | src/intel_device.c | 54 | ||||
-rw-r--r-- | src/intel_driver.h | 2 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 2 |
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)); |