[Libva] [PATCH v3 intel-driver] Add support for new VA buffer export APIs.
Gwenole Beauchesne
gb.devel at gmail.com
Tue Aug 26 02:45:31 PDT 2014
Hi,
2014-08-26 7:34 GMT+02:00 Xiang, Haihao <haihao.xiang at intel.com>:
> 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.
OK, I will address this issue with a couple more patches 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