[Libva] [PATCH v2 6/7] drm: add API to expose VA surface and image buffers.

Gwenole Beauchesne gb.devel at gmail.com
Mon Jul 16 02:04:28 PDT 2012


Add vaGet{Surface,Image}BufferDRM() APIs to retrieve the underlying DRM
buffers to the supplied VA surface or image.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
 va/drm/Makefile.am      |    1 +
 va/drm/va_backend_drm.h |   71 +++++++++++++++++++++++++++++++++++++++++++++++
 va/drm/va_drm.c         |   61 ++++++++++++++++++++++++++++++++++++++++
 va/drm/va_drm.h         |   64 ++++++++++++++++++++++++++++++++++++++++++
 va/va_backend.h         |   10 ++++++-
 5 files changed, 206 insertions(+), 1 deletion(-)
 create mode 100644 va/drm/va_backend_drm.h

diff --git a/va/drm/Makefile.am b/va/drm/Makefile.am
index f38e114..8dab0b3 100644
--- a/va/drm/Makefile.am
+++ b/va/drm/Makefile.am
@@ -33,6 +33,7 @@ source_c = \
 	$(NULL)
 
 source_h = \
+	va_backend_drm.h	\
 	va_drm.h		\
 	$(NULL)
 
diff --git a/va/drm/va_backend_drm.h b/va/drm/va_backend_drm.h
new file mode 100644
index 0000000..aa575c5
--- /dev/null
+++ b/va/drm/va_backend_drm.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_BACKEND_DRM_H
+#define VA_BACKEND_DRM_H
+
+#include <va/va_backend.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \brief VA/DRM API identifier. */
+#define VA_DRM_API_ID           (0x44524d00) /* DRM0 */
+/** \brief VA/DRM API version. */
+#define VA_DRM_API_VERSION      (VA_DRM_API_ID + 1)
+
+/* Forward declarations */
+struct _VABufferInfoDRM;
+
+/** \brief VA/DRM implementation hooks. */
+struct VADriverVTableDRM {
+    /**
+     * \brief Interface version.
+     *
+     * This field is set to \ref VA_DRM_API_VERSION from libva. It is
+     * useful to VA drivers for determining the layout of this VTable.
+     */
+    unsigned int version;
+
+    /** \brief Hook to return DRM buffer info associated with a VA surface. */
+    VAStatus (*vaGetSurfaceBufferDRM)(
+        VADriverContextP         ctx,
+        VASurfaceID              surface,
+        struct _VABufferInfoDRM *out_buffer_info
+    );
+
+    /** \brief Hook to return DRM buffer info associated with a VA image. */
+    VAStatus (*vaGetImageBufferDRM)(
+        VADriverContextP         ctx,
+        VAImageID                image,
+        struct _VABufferInfoDRM *out_buffer_info
+    );
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_BACKEND_DRM_H */
diff --git a/va/drm/va_drm.c b/va/drm/va_drm.c
index b7f60ba..19e7331 100644
--- a/va/drm/va_drm.c
+++ b/va/drm/va_drm.c
@@ -26,6 +26,7 @@
 #include <xf86drm.h>
 #include "va_drm.h"
 #include "va_backend.h"
+#include "va_backend_drm.h"
 #include "va_drmcommon.h"
 #include "va_drm_auth.h"
 
@@ -44,6 +45,7 @@ va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
     if (!pDisplayContext)
         return;
 
+    free(pDisplayContext->pDriverContext->vtable_drm);
     free(pDisplayContext->pDriverContext->drm_state);
     free(pDisplayContext->pDriverContext);
     free(pDisplayContext);
@@ -121,6 +123,7 @@ vaGetDisplayDRM(int fd)
     VADisplayContextP pDisplayContext = NULL;
     VADriverContextP  pDriverContext  = NULL;
     struct drm_state *drm_state       = NULL;
+    struct VADriverVTableDRM *vtable  = NULL;
 
     if (fd < 0)
         return NULL;
@@ -139,6 +142,12 @@ vaGetDisplayDRM(int fd)
     pDriverContext->display_type = VA_DISPLAY_DRM;
     pDriverContext->drm_state    = drm_state;
 
+    vtable = calloc(1, sizeof(*vtable));
+    if (!vtable)
+        goto error;
+    vtable->version = VA_DRM_API_VERSION;
+    pDriverContext->vtable_drm = vtable;
+
     pDisplayContext = calloc(1, sizeof(*pDisplayContext));
     if (!pDisplayContext)
         goto error;
@@ -154,5 +163,57 @@ error:
     free(pDisplayContext);
     free(pDriverContext);
     free(drm_state);
+    free(vtable);
     return NULL;
 }
+
+#define INIT_CONTEXT(ctx, dpy) do {                             \
+        if (!vaDisplayIsValid(dpy))                             \
+            return VA_STATUS_ERROR_INVALID_DISPLAY;             \
+                                                                \
+        ctx = ((VADisplayContextP)(dpy))->pDriverContext;       \
+        if (!(ctx))                                             \
+            return VA_STATUS_ERROR_INVALID_DISPLAY;             \
+    } while (0)
+
+#define INVOKE(ctx, func, args) do {                            \
+        struct VADriverVTableDRM * const vtable =               \
+            (ctx)->vtable_drm;                                  \
+        if (!vtable || !vtable->va##func##DRM)                  \
+            return VA_STATUS_ERROR_UNIMPLEMENTED;               \
+        status = vtable->va##func##DRM args;                    \
+    } while (0)
+
+// Returns the underlying DRM buffer to the supplied VA surface
+VAStatus
+vaGetSurfaceBufferDRM(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    VABufferInfoDRM    *out_buffer_info
+)
+{
+    VADriverContextP ctx;
+    VAStatus status;
+
+    INIT_CONTEXT(ctx, dpy);
+
+    INVOKE(ctx, GetSurfaceBuffer, (ctx, surface, out_buffer_info));
+    return status;
+}
+
+// Returns the underlying DRM buffer to the supplied VA image
+VAStatus
+vaGetImageBufferDRM(
+    VADisplay           dpy,
+    VAImageID           image,
+    VABufferInfoDRM    *out_buffer_info
+)
+{
+    VADriverContextP ctx;
+    VAStatus status;
+
+    INIT_CONTEXT(ctx, dpy);
+
+    INVOKE(ctx, GetImageBuffer, (ctx, image, out_buffer_info));
+    return status;
+}
diff --git a/va/drm/va_drm.h b/va/drm/va_drm.h
index 9af3cc8..34b90ff 100644
--- a/va/drm/va_drm.h
+++ b/va/drm/va_drm.h
@@ -40,6 +40,26 @@
 extern "C" {
 #endif
 
+#include <stdint.h>
+
+/** \brief VA Buffer info specific to the DRM backend. */
+typedef struct _VABufferInfoDRM {
+    /** \brief Native DRM buffer handle (name). */
+    uintptr_t           handle;
+    /** \brief Buffer format as a fourcc value, see VA_FOURCC_xxx. */
+    uint32_t            fourcc;
+    /** \brief Width in pixels for the DRM image. */
+    uint16_t            width;
+    /** \brief Height in pixels for the DRM image. */
+    uint16_t            height;
+    /** \brief Number of planes associated to this DRM image. */
+    uint32_t            num_planes;
+    /** \brief Number of bytes for a line stride. */
+    uint32_t            pitches[3];
+    /** \brief Number of bytes to add from base to reach the specified plane. */
+    intptr_t            offsets[3];
+} VABufferInfoDRM;
+
 /**
  * \brief Returns a VA display derived from the specified DRM connection.
  *
@@ -52,6 +72,50 @@ extern "C" {
 VADisplay
 vaGetDisplayDRM(int fd);
 
+/**
+ * \brief Returns the DRM buffer name associated with a VA surface.
+ *
+ * This function returns the underlying DRM buffer handle for the supplied
+ * VA @surface. Additional information is also filled into @out_buffer_info
+ * so that to describe the layout of the associated DRM buffer.
+ *
+ * @param[in]   dpy     the VA display
+ * @param[in]   surface the VA surface
+ * @param[out]  out_buffer_info the returned VA/DRM buffer information
+ * @return VA_STATUS_SUCCESS if operation is successful, another #VAStatus
+ *     value otherwise.
+ */
+VAStatus
+vaGetSurfaceBufferDRM(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    VABufferInfoDRM    *out_buffer_info
+);
+
+/**
+ * \brief Returns the DRM buffer name associated with a VA image.
+ *
+ * This function returns the underlying DRM buffer handle for the
+ * supplied VA @image. Additional information is also filled into
+ * @out_buffer_info so that to describe the layout of the associated
+ * DRM buffer.
+ *
+ * Note: paletted formats are not supported. In this case,
+ * VA_STATUS_ERROR_INVALID_IMAGE_FORMAT is returned.
+ *
+ * @param[in]   dpy     the VA display
+ * @param[in]   image   the VA image
+ * @param[out]  out_buffer_info the returned VA/DRM buffer information
+ * @return VA_STATUS_SUCCESS if operation is successful, another #VAStatus
+ *     value otherwise.
+ */
+VAStatus
+vaGetImageBufferDRM(
+    VADisplay           dpy,
+    VAImageID           image,
+    VABufferInfoDRM    *out_buffer_info
+);
+
 /**@}*/
 
 #ifdef __cplusplus
diff --git a/va/va_backend.h b/va/va_backend.h
index 6c7177e..83143c5 100644
--- a/va/va_backend.h
+++ b/va/va_backend.h
@@ -492,7 +492,15 @@ struct VADriverContext
     /** \brief VA display type. */
     unsigned long display_type;
 
-    unsigned long reserved[43];         /* reserve for future add-ins, decrease the subscript accordingly */
+    /**
+     * \brief The VA/DRM implementation hooks.
+     *
+     * This structure is allocated from libva with calloc(). Valid
+     * only if @display_type is #VA_DISPLAY_DRM.
+     */
+    struct VADriverVTableDRM *vtable_drm;
+
+    unsigned long reserved[42];         /* reserve for future add-ins, decrease the subscript accordingly */
 };
 
 #define VA_DISPLAY_MAGIC 0x56414430 /* VAD0 */
-- 
1.7.9.5



More information about the Libva mailing list