[Libva] [PATCH v3 intel-driver] Add support for new VA buffer export APIs.
Xiang, Haihao
haihao.xiang at intel.com
Fri Aug 22 01:48:59 PDT 2014
> 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 ? If the buffer is
locked for external usage, can the driver write the corresponding VA
surface internally ?
>
> 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
More information about the Libva
mailing list