[Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()
Leo Liu
leo.liu at amd.com
Sat Oct 7 14:23:01 UTC 2017
On 2017-10-01 01:40 PM, Mark Thompson wrote:
> This is a new interface in libva2 to support wider use-cases of passing
> surfaces to external APIs. In particular, this allows export of NV12 and
> P010 surfaces.
>
> v2: Convert surfaces to progressive before exporting them (Christian).
>
> v3: Set destination rectangle to match source when converting (Leo).
> Add guards to allow building with libva1.
>
> Signed-off-by: Mark Thompson <sw at jkqxz.net>
This patch is Acked-and-Tested-by: Leo Liu< leo.liu at amd.com>, also pushed.
Regards,
Leo
> ---
> src/gallium/state_trackers/va/context.c | 5 +-
> src/gallium/state_trackers/va/surface.c | 148 +++++++++++++++++++++++++++++
> src/gallium/state_trackers/va/va_private.h | 1 +
> 3 files changed, 153 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c
> index f2cb37aa22..1207499a78 100644
> --- a/src/gallium/state_trackers/va/context.c
> +++ b/src/gallium/state_trackers/va/context.c
> @@ -88,7 +88,10 @@ static struct VADriverVTable vtable =
> &vlVaCreateSurfaces2,
> &vlVaQuerySurfaceAttributes,
> &vlVaAcquireBufferHandle,
> - &vlVaReleaseBufferHandle
> + &vlVaReleaseBufferHandle,
> +#if VA_CHECK_VERSION(1, 0, 0)
> + &vlVaExportSurfaceHandle,
> +#endif
> };
>
> static struct VADriverVTableVPP vtable_vpp =
> diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
> index 643cdcd54a..e37b17b001 100644
> --- a/src/gallium/state_trackers/va/surface.c
> +++ b/src/gallium/state_trackers/va/surface.c
> @@ -44,6 +44,7 @@
> #include "va_private.h"
>
> #include <va/va_drmcommon.h>
> +#include <drm-uapi/drm_fourcc.h>
>
> static const enum pipe_format vpp_surface_formats[] = {
> PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
> @@ -889,3 +890,150 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, VAContextID context,
>
> return VA_STATUS_SUCCESS;
> }
> +
> +#if VA_CHECK_VERSION(1, 0, 0)
> +VAStatus
> +vlVaExportSurfaceHandle(VADriverContextP ctx,
> + VASurfaceID surface_id,
> + uint32_t mem_type,
> + uint32_t flags,
> + void *descriptor)
> +{
> + vlVaDriver *drv;
> + vlVaSurface *surf;
> + struct pipe_surface **surfaces;
> + struct pipe_screen *screen;
> + VAStatus ret;
> + unsigned int usage;
> + int i, p;
> +
> + VADRMPRIMESurfaceDescriptor *desc = descriptor;
> +
> + if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
> + return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
> + if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
> + return VA_STATUS_ERROR_INVALID_SURFACE;
> +
> + drv = VL_VA_DRIVER(ctx);
> + screen = VL_VA_PSCREEN(ctx);
> + mtx_lock(&drv->mutex);
> +
> + surf = handle_table_get(drv->htab, surface_id);
> + if (!surf || !surf->buffer) {
> + mtx_unlock(&drv->mutex);
> + return VA_STATUS_ERROR_INVALID_SURFACE;
> + }
> +
> + if (surf->buffer->interlaced) {
> + struct pipe_video_buffer *interlaced = surf->buffer;
> + struct u_rect src_rect, dst_rect;
> +
> + surf->templat.interlaced = false;
> +
> + ret = vlVaHandleSurfaceAllocate(drv, surf, &surf->templat);
> + if (ret != VA_STATUS_SUCCESS) {
> + mtx_unlock(&drv->mutex);
> + return VA_STATUS_ERROR_ALLOCATION_FAILED;
> + }
> +
> + src_rect.x0 = dst_rect.x0 = 0;
> + src_rect.y0 = dst_rect.y0 = 0;
> + src_rect.x1 = dst_rect.x1 = surf->templat.width;
> + src_rect.y1 = dst_rect.y1 = surf->templat.height;
> +
> + vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
> + interlaced, surf->buffer,
> + &src_rect, &dst_rect,
> + VL_COMPOSITOR_WEAVE);
> +
> + interlaced->destroy(interlaced);
> + }
> +
> + surfaces = surf->buffer->get_surfaces(surf->buffer);
> +
> + usage = 0;
> + if (flags & VA_EXPORT_SURFACE_READ_ONLY)
> + usage |= PIPE_HANDLE_USAGE_READ;
> + if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
> + usage |= PIPE_HANDLE_USAGE_WRITE;
> +
> + desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
> + desc->width = surf->buffer->width;
> + desc->height = surf->buffer->height;
> +
> + for (p = 0; p < VL_MAX_SURFACES; p++) {
> + struct winsys_handle whandle;
> + struct pipe_resource *resource;
> + uint32_t drm_format;
> +
> + if (!surfaces[p])
> + break;
> +
> + resource = surfaces[p]->texture;
> +
> + switch (resource->format) {
> + case PIPE_FORMAT_R8_UNORM:
> + drm_format = DRM_FORMAT_R8;
> + break;
> + case PIPE_FORMAT_R8G8_UNORM:
> + drm_format = DRM_FORMAT_GR88;
> + break;
> + case PIPE_FORMAT_R16_UNORM:
> + drm_format = DRM_FORMAT_R16;
> + break;
> + case PIPE_FORMAT_R16G16_UNORM:
> + drm_format = DRM_FORMAT_GR1616;
> + break;
> + case PIPE_FORMAT_B8G8R8A8_UNORM:
> + drm_format = DRM_FORMAT_ARGB8888;
> + break;
> + case PIPE_FORMAT_R8G8B8A8_UNORM:
> + drm_format = DRM_FORMAT_ABGR8888;
> + break;
> + case PIPE_FORMAT_B8G8R8X8_UNORM:
> + drm_format = DRM_FORMAT_XRGB8888;
> + break;
> + case PIPE_FORMAT_R8G8B8X8_UNORM:
> + drm_format = DRM_FORMAT_XBGR8888;
> + break;
> + default:
> + ret = VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
> + goto fail;
> + }
> +
> + memset(&whandle, 0, sizeof(whandle));
> + whandle.type = DRM_API_HANDLE_TYPE_FD;
> +
> + if (!screen->resource_get_handle(screen, drv->pipe, resource,
> + &whandle, usage)) {
> + ret = VA_STATUS_ERROR_INVALID_SURFACE;
> + goto fail;
> + }
> +
> + desc->objects[p].fd = (int)whandle.handle;
> + desc->objects[p].size = 0;
> + desc->objects[p].drm_format_modifier = whandle.modifier;
> +
> + desc->layers[p].drm_format = drm_format;
> + desc->layers[p].num_planes = 1;
> + desc->layers[p].object_index[0] = p;
> + desc->layers[p].offset[0] = whandle.offset;
> + desc->layers[p].pitch[0] = whandle.stride;
> + }
> +
> + desc->num_objects = p;
> + desc->num_layers = p;
> +
> + mtx_unlock(&drv->mutex);
> +
> + return VA_STATUS_SUCCESS;
> +
> +fail:
> + for (i = 0; i < p; i++)
> + close(desc->objects[i].fd);
> +
> + mtx_unlock(&drv->mutex);
> +
> + return ret;
> +}
> +#endif
> diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
> index 61712ce913..46f6ba66f2 100644
> --- a/src/gallium/state_trackers/va/va_private.h
> +++ b/src/gallium/state_trackers/va/va_private.h
> @@ -394,6 +394,7 @@ VAStatus vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config, VAS
>
> VAStatus vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, VABufferInfo *out_buf_info);
> VAStatus vlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id);
> +VAStatus vlVaExportSurfaceHandle(VADriverContextP ctx, VASurfaceID surface_id, uint32_t mem_type, uint32_t flags, void *descriptor);
>
> VAStatus vlVaQueryVideoProcFilters(VADriverContextP ctx, VAContextID context, VAProcFilterType *filters,
> unsigned int *num_filters);
More information about the mesa-dev
mailing list