Hi, 2014-08-26 7:34 GMT+02:00 Xiang, Haihao <[email protected]>: > On Mon, 2014-08-25 at 11:44 +0200, Gwenole Beauchesne wrote: >> Hi, >> >> 2014-08-22 10:48 GMT+02:00 Xiang, Haihao <[email protected]>: >> > >> >> 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 <[email protected]> >> >> --- >> >> 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 _______________________________________________ Libva mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libva
