[Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

Christian König ckoenig.leichtzumerken at gmail.com
Wed Sep 20 08:14:32 UTC 2017


Am 20.09.2017 um 00:01 schrieb Mark Thompson:
> 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.

First of all thanks a lot for taking care of this.

> Signed-off-by: Mark Thompson <sw at jkqxz.net>
> ---
> Trivial update for a minor change requested on libva side (1/2 identical).
>
> Still unsure on what to do about size and interlacing.  I'll have a look at the postproc code just posted soon, though I think it's pretty much entirely orthogonal to this.

Probably best to convert the interlaced representation into the 
progressive form before exporting.

Only alternative I can think of is to define new DRM 
formats/modifiers/attributes, but then the application needs to be aware 
of this as well.

Anyway patch is Acked-by: Christian König <christian.koenig at amd.com> for 
now.

Regards,
Christian.

>
> Thanks,
>
> - Mark
>
>
>   src/gallium/state_trackers/va/context.c    |   3 +-
>   src/gallium/state_trackers/va/surface.c    | 121 +++++++++++++++++++++++++++++
>   src/gallium/state_trackers/va/va_private.h |   1 +
>   3 files changed, 124 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c
> index f2cb37aa22..2794e5c733 100644
> --- a/src/gallium/state_trackers/va/context.c
> +++ b/src/gallium/state_trackers/va/context.c
> @@ -88,7 +88,8 @@ static struct VADriverVTable vtable =
>      &vlVaCreateSurfaces2,
>      &vlVaQuerySurfaceAttributes,
>      &vlVaAcquireBufferHandle,
> -   &vlVaReleaseBufferHandle
> +   &vlVaReleaseBufferHandle,
> +   &vlVaExportSurfaceHandle
>   };
>   
>   static struct VADriverVTableVPP vtable_vpp =
> diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
> index 67773cf76a..b4ae5b3c34 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,
> @@ -892,3 +893,123 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, VAContextID context,
>   
>      return VA_STATUS_SUCCESS;
>   }
> +
> +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;
> +   }
> +
> +   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;
> +}
> diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
> index 5b1b832bb0..4f447008a6 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