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

Gwenole Beauchesne gb.devel at gmail.com
Mon Aug 25 02:44:03 PDT 2014


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?

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