[Libva] [Libva-intel-driver PATCH 6/9] Add the support of wrapper the VA Buffer to the backend driver

Zhao Yakui yakui.zhao at intel.com
Sat Sep 5 18:39:13 PDT 2015


The obj_context is passed when calling vaCreateBuffer, which can be
used to check whether it belongs to the wrapped context. If one VA buffer
belongs to wrapped buffer, the callback function of backend driver will
be called for the corresponding VA buffer.

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Signed-off-by: Sean V Kelley <seanvk at posteo.de>
---
 src/i965_drv_video.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 33c95b0..a47cd2c 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -2162,6 +2162,8 @@ i965_create_buffer_internal(VADriverContextP ctx,
     struct buffer_store *buffer_store = NULL;
     int bufferID;
     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+    struct object_context *obj_context = CONTEXT(context);
+    int wrapper_flag = 0;
 
     /* Validate type */
     switch (type) {
@@ -2218,22 +2220,54 @@ i965_create_buffer_internal(VADriverContextP ctx,
     assert(buffer_store);
     buffer_store->ref_count = 1;
 
+    if (obj_context &&
+        (obj_context->wrapper_context != VA_INVALID_ID) &&
+        i965->wrapper_pdrvctx) {
+        VAGenericID wrapper_buffer;
+        VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+        CALL_VTABLE(pdrvctx, vaStatus,
+                    vaCreateBuffer(pdrvctx, obj_context->wrapper_context, type, size, num_elements,
+                                   data, &wrapper_buffer));
+        if (vaStatus == VA_STATUS_SUCCESS) {
+            obj_buffer->wrapper_buffer = wrapper_buffer;
+        } else {
+            free(buffer_store);
+            return vaStatus;
+        }
+        wrapper_flag = 1;
+    }
+
     if (store_bo != NULL) {
         buffer_store->bo = store_bo;
         dri_bo_reference(buffer_store->bo);
-        
-        if (data)
+
+        /* If the buffer is wrapped, the buffer_store is bogus. Unnecessary to copy it */
+        if (data && !wrapper_flag)
             dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
     } else if (type == VASliceDataBufferType || 
                type == VAImageBufferType || 
                type == VAEncCodedBufferType ||
                type == VAProbabilityBufferType) {
-        buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, 
-                                        "Buffer", 
-                                        size * num_elements, 64);
+
+        /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
+         * So it is enough to allocate one 64 byte bo
+         */
+        if (wrapper_flag)
+            buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, "Bogus buffer",
+                                            64, 64);
+        else
+            buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
+                                            "Buffer",
+                                            size * num_elements, 64);
         assert(buffer_store->bo);
 
-        if (type == VAEncCodedBufferType) {
+        /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
+         * In fact it can be skipped. But it is still allocated and it is
+         * only to follow the normal flowchart of buffer_allocation/release.
+         */
+        if (!wrapper_flag) {
+          if (type == VAEncCodedBufferType) {
             struct i965_coded_buffer_segment *coded_buffer_segment;
 
             dri_bo_map(buffer_store->bo, 1);
@@ -2246,9 +2280,10 @@ i965_create_buffer_internal(VADriverContextP ctx,
             coded_buffer_segment->mapped = 0;
             coded_buffer_segment->codec = 0;
             dri_bo_unmap(buffer_store->bo);
-        } else if (data) {
-            dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
-        }
+          } else if (data) {
+              dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
+          }
+       }
 
     } else {
         int msize = size;
@@ -2257,10 +2292,14 @@ i965_create_buffer_internal(VADriverContextP ctx,
             msize = ALIGN(size, 4);
         }
 
-        buffer_store->buffer = malloc(msize * num_elements);
+        /* If the buffer is wrapped, it is enough to allocate 4 bytes */
+        if (wrapper_flag)
+            buffer_store->buffer = malloc(4);
+        else
+            buffer_store->buffer = malloc(msize * num_elements);
         assert(buffer_store->buffer);
 
-        if (data)
+        if (data && (!wrapper_flag))
             memcpy(buffer_store->buffer, data, size * num_elements);
     }
 
@@ -2296,6 +2335,19 @@ i965_BufferSetNumElements(VADriverContextP ctx,
 
     ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
 
+    /* When the wrapper_buffer exists, it will wrapper to the
+     * buffer allocated from backend driver.
+     */
+    if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
+        i965->wrapper_pdrvctx) {
+        VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+        CALL_VTABLE(pdrvctx, vaStatus,
+                    vaBufferSetNumElements(pdrvctx, obj_buffer->wrapper_buffer,
+                                         num_elements));
+        return vaStatus;
+    }
+
     if ((num_elements < 0) || 
         (num_elements > obj_buffer->max_num_elements)) {
         vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
@@ -2319,6 +2371,19 @@ i965_MapBuffer(VADriverContextP ctx,
     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
 
     ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
+
+    /* When the wrapper_buffer exists, it will wrapper to the
+     * buffer allocated from backend driver.
+     */
+    if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
+        i965->wrapper_pdrvctx) {
+        VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+        CALL_VTABLE(pdrvctx, vaStatus,
+                    vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer, pbuf));
+        return vaStatus;
+    }
+
     ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
     ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
 
@@ -2431,6 +2496,18 @@ i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
         return VA_STATUS_ERROR_INVALID_BUFFER;
 
     ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
+    /* When the wrapper_buffer exists, it will wrapper to the
+     * buffer allocated from backend driver.
+     */
+    if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
+        i965->wrapper_pdrvctx) {
+        VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+        CALL_VTABLE(pdrvctx, vaStatus,
+                    vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
+        return vaStatus;
+    }
+
     ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
     ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
 
@@ -5449,6 +5526,16 @@ i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
     if (obj_buffer->type != VAImageBufferType)
         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
 
+    /*
+     * As the allocated buffer by calling vaCreateBuffer is related with
+     * the specific context, it is unnecessary to export it.
+     * So it is not supported when the buffer is allocated from wrapped
+     * backend dirver.
+     */
+    if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
+        return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
+    }
+
     if (!buf_info)
         return VA_STATUS_ERROR_INVALID_PARAMETER;
 
@@ -5478,6 +5565,10 @@ i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
     if (!obj_buffer)
         return VA_STATUS_ERROR_INVALID_BUFFER;
 
+    if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
+        return VA_STATUS_ERROR_INVALID_BUFFER;
+    }
+
     return i965_release_buffer_handle(obj_buffer);
 }
 
-- 
1.8.4.2



More information about the Libva mailing list