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

Gwenole Beauchesne gb.devel at gmail.com
Wed Aug 13 09:50:07 PDT 2014


Hi,

2014-08-13 18:45 GMT+02:00 Gwenole Beauchesne <gb.devel at gmail.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.
>
> 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>

The previously acquired PRIME fd is now closed on release. The fd is
owned by the driver, so upper layers are expected to dup() it whenever
necessary. This is inline with other usages, most notably
EGL_image_dma_buf_import #6.

Note: we would also need improved thread-safety. But this is a global
issue, for other objects too. Though, I added provisions to get it
supported simply in context of object_buffer.

> ---
>  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
> --
> 1.7.9.5
>



-- 
Gwenole Beauchesne
Intel Corporation SAS / 2 rue de Paris, 92196 Meudon Cedex, France
Registration Number (RCS): Nanterre B 302 456 199


More information about the Libva mailing list