[Libva] [PATCH 1/2] drm: add support for render nodes.

Gwenole Beauchesne gb.devel at gmail.com
Wed Sep 24 01:40:02 PDT 2014


From: Andrey Larionov <andrey.larionov at intel.com>

Allow vaGetDisplayDRM() to accept DRM Render-Nodes file descriptors,
thus skipping authentication burdens in that case. This also allows
remote users, connected through ssh for instance, to enjoy hardware
acceleration even if there is a local display opened (user logged in).

Signed-off-by: Andrey Larionov <andrey.larionov at intel.com>
[checked if fd is a render-node, fixed VA_DISPLAY_DRM_RENDERNODES]
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
 va/drm/va_drm.c       | 28 +++++++++++++++++-----------
 va/drm/va_drm_utils.c | 21 +++++++++++++++++++++
 va/drm/va_drm_utils.h | 10 ++++++++++
 va/va_backend.h       |  2 ++
 4 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/va/drm/va_drm.c b/va/drm/va_drm.c
index 25bf8bb..08071cf 100644
--- a/va/drm/va_drm.c
+++ b/va/drm/va_drm.c
@@ -36,7 +36,8 @@ va_DisplayContextIsValid(VADisplayContextP pDisplayContext)
     VADriverContextP const pDriverContext = pDisplayContext->pDriverContext;
 
     return (pDriverContext &&
-            pDriverContext->display_type == VA_DISPLAY_DRM);
+            ((pDriverContext->display_type & VA_DISPLAY_MAJOR_MASK) ==
+             VA_DISPLAY_DRM));
 }
 
 static void
@@ -67,15 +68,18 @@ va_DisplayContextGetDriverName(
     if (status != VA_STATUS_SUCCESS)
         return status;
 
-    ret = drmGetMagic(drm_state->fd, &magic);
-    if (ret < 0)
-        return VA_STATUS_ERROR_OPERATION_FAILED;
-
-    if (!va_drm_is_authenticated(drm_state->fd)) {
-        if (!va_drm_authenticate(drm_state->fd, magic))
-            return VA_STATUS_ERROR_OPERATION_FAILED;
-        if (!va_drm_is_authenticated(drm_state->fd))
+    /* Authentication is only needed for a legacy DRM device */
+    if (ctx->display_type != VA_DISPLAY_DRM_RENDERNODES) {
+        ret = drmGetMagic(drm_state->fd, &magic);
+        if (ret < 0)
             return VA_STATUS_ERROR_OPERATION_FAILED;
+
+        if (!va_drm_is_authenticated(drm_state->fd)) {
+            if (!va_drm_authenticate(drm_state->fd, magic))
+                return VA_STATUS_ERROR_OPERATION_FAILED;
+            if (!va_drm_is_authenticated(drm_state->fd))
+                return VA_STATUS_ERROR_OPERATION_FAILED;
+        }
     }
 
     drm_state->auth_type = VA_DRM_AUTH_CUSTOM;
@@ -89,8 +93,9 @@ vaGetDisplayDRM(int fd)
     VADisplayContextP pDisplayContext = NULL;
     VADriverContextP  pDriverContext  = NULL;
     struct drm_state *drm_state       = NULL;
+    int is_render_nodes;
 
-    if (fd < 0)
+    if (fd < 0 || (is_render_nodes = VA_DRM_IsRenderNodeFd(fd)) < 0)
         return NULL;
 
     /* Create new entry */
@@ -104,7 +109,8 @@ vaGetDisplayDRM(int fd)
     if (!pDriverContext)
         goto error;
     pDriverContext->native_dpy   = NULL;
-    pDriverContext->display_type = VA_DISPLAY_DRM;
+    pDriverContext->display_type = is_render_nodes ?
+        VA_DISPLAY_DRM_RENDERNODES : VA_DISPLAY_DRM;
     pDriverContext->drm_state    = drm_state;
 
     pDisplayContext = calloc(1, sizeof(*pDisplayContext));
diff --git a/va/drm/va_drm_utils.c b/va/drm/va_drm_utils.c
index da0ade2..71091fd 100644
--- a/va/drm/va_drm_utils.c
+++ b/va/drm/va_drm_utils.c
@@ -26,6 +26,7 @@
 
 #include "sysdeps.h"
 #include <xf86drm.h>
+#include <sys/stat.h>
 #include "va_drm_utils.h"
 #include "va_drmcommon.h"
 
@@ -78,3 +79,23 @@ VA_DRM_GetDriverName(VADriverContextP ctx, char **driver_name_ptr)
     *driver_name_ptr = driver_name;
     return VA_STATUS_SUCCESS;
 }
+
+/* Checks whether the file descriptor is a DRM Render-Nodes one */
+int
+VA_DRM_IsRenderNodeFd(int fd)
+{
+    struct stat st;
+    const char *name;
+
+    /* Check by device node */
+    if (fstat(fd, &st) == 0)
+        return S_ISCHR(st.st_mode) && (st.st_rdev & 0x80);
+
+    /* Check by device name */
+    name = drmGetDeviceNameFromFd(fd);
+    if (name)
+        return strncmp(name, "/dev/dri/renderD", 16) == 0;
+
+    /* Unrecoverable error */
+    return -1;
+}
diff --git a/va/drm/va_drm_utils.h b/va/drm/va_drm_utils.h
index 0cb361e..b468c59 100644
--- a/va/drm/va_drm_utils.h
+++ b/va/drm/va_drm_utils.h
@@ -64,6 +64,16 @@ DLL_HIDDEN
 VAStatus
 VA_DRM_GetDriverName(VADriverContextP ctx, char **driver_name_ptr);
 
+/**
+ * \brief Checks whether the file descriptor is a DRM Render-Nodes one
+ *
+ * This functions checks whether the supplied file descriptor @fd
+ * falls into the set of DRM Render-Nodes.
+ */
+DLL_HIDDEN
+int
+VA_DRM_IsRenderNodeFd(int fd);
+
 /**@}*/
 
 #ifdef __cplusplus
diff --git a/va/va_backend.h b/va/va_backend.h
index 5e8dc42..40d3031 100644
--- a/va/va_backend.h
+++ b/va/va_backend.h
@@ -48,6 +48,8 @@ enum {
     VA_DISPLAY_ANDROID  = 0x20,
     /** \brief VA/DRM API is used, through vaGetDisplayDRM() entry-point. */
     VA_DISPLAY_DRM      = 0x30,
+    /** \brief VA/DRM API is used, with a render-node device path */
+    VA_DISPLAY_DRM_RENDERNODES = (VA_DISPLAY_DRM | (1 << 0)),
     /** \brief VA/Wayland API is used, through vaGetDisplayWl() entry-point. */
     VA_DISPLAY_WAYLAND  = 0x40,
 };
-- 
1.9.1



More information about the Libva mailing list