[Libva] [PATCH v3 intel-driver] Add support for new VA buffer export APIs.

Xiang, Haihao haihao.xiang at intel.com
Mon Aug 25 22:34:18 PDT 2014


On Mon, 2014-08-25 at 11:44 +0200, Gwenole Beauchesne wrote:
> Hi,
> 
> 2014-08-22 10:48 GMT+02:00 Xiang, Haihao <haihao.xiang at intel.com>:
> >
> >> Implement va{Acquire,Release}BufferHandle() hooks so that to allow
> >> VA surface or VA image buffer sharing with thirdparty APIs like EGL,
> >> OpenCL, etc.
> >
> > The type of the 2nd parameter of vaAcquireBufferHandle() is VABufferID,
> > so user can't use the two APIs directly for a VA surface, instead user
> > has to derive an VA image from a VA surface, then exports the image data
> > buffer (a VA buffer) for sharing, is that true ?
> 
> Yes. There is no real reason to provide the same APIs for both
> surfaces and images, especially since the common ground is VA buffers.
> Besides, VA buffer granularity allows for other usages, not related to
> VA surfaces or VA images.
> 
> >  If the buffer is
> > locked for external usage, can the driver write the corresponding VA
> > surface internally ?
> 
> No, why would this be allowed, and how is this going to be in sync then?

I also think it is no, however the current implementation allows user
writing the surface even the corresponding buffer is locked for external
usage.

> 
> >> v2: made sure to sync bo before export, improved VA buffer type check.
> >> v3: tracked internal resources on acquire, disposed them on release.
> >
> >> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
> >> ---
> >>  src/i965_drv_video.c |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  src/i965_drv_video.h |    4 ++
> >>  2 files changed, 133 insertions(+)
> >>
> >> diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
> >> index 32a7c72..92cbf9a 100755
> >> --- a/src/i965_drv_video.c
> >> +++ b/src/i965_drv_video.c
> >> @@ -28,6 +28,7 @@
> >>   */
> >>
> >>  #include "sysdeps.h"
> >> +#include <unistd.h>
> >>
> >>  #ifdef HAVE_VA_X11
> >>  # include "i965_output_dri.h"
> >> @@ -5161,6 +5162,130 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
> >>      return vaStatus;
> >>  }
> >>
> >> +/* Acquires buffer handle for external API usage (internal implementation) */
> >> +static VAStatus
> >> +i965_acquire_buffer_handle(struct object_buffer *obj_buffer,
> >> +    uint32_t mem_type, VABufferInfo *out_buf_info)
> >> +{
> >> +    struct buffer_store *buffer_store;
> >> +
> >> +    buffer_store = obj_buffer->buffer_store;
> >> +    if (!buffer_store || !buffer_store->bo)
> >> +        return VA_STATUS_ERROR_INVALID_BUFFER;
> >> +
> >> +    /* Synchronization point */
> >> +    drm_intel_bo_wait_rendering(buffer_store->bo);
> >> +
> >> +    if (obj_buffer->export_refcount > 0) {
> >> +        if (obj_buffer->export_state.mem_type != mem_type)
> >> +            return VA_STATUS_ERROR_INVALID_PARAMETER;
> >> +    }
> >> +    else {
> >> +        VABufferInfo * const buf_info = &obj_buffer->export_state;
> >> +
> >> +        switch (mem_type) {
> >> +        case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: {
> >> +            uint32_t name;
> >> +            if (drm_intel_bo_flink(buffer_store->bo, &name) != 0)
> >> +                return VA_STATUS_ERROR_INVALID_BUFFER;
> >> +            buf_info->handle = name;
> >> +            break;
> >> +        }
> >> +        case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
> >> +            int fd;
> >> +            if (drm_intel_bo_gem_export_to_prime(buffer_store->bo, &fd) != 0)
> >> +                return VA_STATUS_ERROR_INVALID_BUFFER;
> >> +            buf_info->handle = (intptr_t)fd;
> >> +            break;
> >> +        }
> >> +        }
> >> +
> >> +        buf_info->type = obj_buffer->type;
> >> +        buf_info->mem_type = mem_type;
> >> +        buf_info->mem_size =
> >> +            obj_buffer->num_elements * obj_buffer->size_element;
> >> +    }
> >> +
> >> +    obj_buffer->export_refcount++;
> >> +    *out_buf_info = obj_buffer->export_state;
> >> +    return VA_STATUS_SUCCESS;
> >> +}
> >> +
> >> +/* Releases buffer handle after usage (internal implementation) */
> >> +static VAStatus
> >> +i965_release_buffer_handle(struct object_buffer *obj_buffer)
> >> +{
> >> +    if (obj_buffer->export_refcount == 0)
> >> +        return VA_STATUS_ERROR_INVALID_BUFFER;
> >> +
> >> +    if (--obj_buffer->export_refcount == 0) {
> >> +        VABufferInfo * const buf_info = &obj_buffer->export_state;
> >> +
> >> +        switch (buf_info->mem_type) {
> >> +        case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
> >> +            close((intptr_t)buf_info->handle);
> >> +            break;
> >> +        }
> >> +        }
> >> +        buf_info->mem_type = 0;
> >> +    }
> >> +    return VA_STATUS_SUCCESS;
> >> +}
> >> +
> >> +/** Acquires buffer handle for external API usage */
> >> +static VAStatus
> >> +i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
> >> +    VABufferInfo *buf_info)
> >> +{
> >> +    struct i965_driver_data * const i965 = i965_driver_data(ctx);
> >> +    struct object_buffer * const obj_buffer = BUFFER(buf_id);
> >> +    uint32_t i, mem_type;
> >> +
> >> +    /* List of supported memory types, in preferred order */
> >> +    static const uint32_t mem_types[] = {
> >> +        VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
> >> +        VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM,
> >> +        0
> >> +    };
> >> +
> >> +    if (!obj_buffer)
> >> +        return VA_STATUS_ERROR_INVALID_BUFFER;
> >> +    /* XXX: only VA surface|image like buffers are supported for now */
> >> +    if (obj_buffer->type != VAImageBufferType)
> >> +        return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
> >> +
> >> +    if (!buf_info)
> >> +        return VA_STATUS_ERROR_INVALID_PARAMETER;
> >> +
> >> +    if (!buf_info->mem_type)
> >> +        mem_type = mem_types[0];
> >> +    else {
> >> +        mem_type = 0;
> >> +        for (i = 0; mem_types[i] != 0; i++) {
> >> +            if (buf_info->mem_type & mem_types[i]) {
> >> +                mem_type = buf_info->mem_type;
> >> +                break;
> >> +            }
> >> +        }
> >> +        if (!mem_type)
> >> +            return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
> >> +    }
> >> +    return i965_acquire_buffer_handle(obj_buffer, mem_type, buf_info);
> >> +}
> >> +
> >> +/** Releases buffer handle after usage from external API */
> >> +static VAStatus
> >> +i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
> >> +{
> >> +    struct i965_driver_data * const i965 = i965_driver_data(ctx);
> >> +    struct object_buffer * const obj_buffer = BUFFER(buf_id);
> >> +
> >> +    if (!obj_buffer)
> >> +        return VA_STATUS_ERROR_INVALID_BUFFER;
> >> +
> >> +    return i965_release_buffer_handle(obj_buffer);
> >> +}
> >> +
> >>  static int
> >>  i965_os_has_ring_support(VADriverContextP ctx,
> >>                           int ring)
> >> @@ -5690,6 +5815,10 @@ VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
> >>      vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
> >>      vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
> >>
> >> +    /* 0.36.0 */
> >> +    vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle;
> >> +    vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle;
> >> +
> >>      vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
> >>      vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
> >>      vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
> >> diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
> >> index ee4b163..145071f 100644
> >> --- a/src/i965_drv_video.h
> >> +++ b/src/i965_drv_video.h
> >> @@ -287,6 +287,10 @@ struct object_buffer
> >>      int num_elements;
> >>      int size_element;
> >>      VABufferType type;
> >> +
> >> +    /* Export state */
> >> +    unsigned int export_refcount;
> >> +    VABufferInfo export_state;
> >>  };
> >>
> >>  struct object_image
> >
> >
> 
> Regards,




More information about the Libva mailing list