[Mesa-dev] [PATCH v2] st/va: ensure linear memory for dmabuf

Christian König deathsimple at vodafone.de
Wed Jun 8 08:16:52 UTC 2016


Am 02.06.2016 um 16:00 schrieb Julien Isorce:
> In order to do zero-copy between two different devices
> the memory should not be tiled.
>
> This is currently no way to set pipe_resource template's flag
> from pipe_video_buffer template. So disabled_tiling is added.
>
> Choosed "disable" prefix so that CALLOC keeps tiling enabled
> by default.
>
> Tested with GStreamer on a laptop that has 2 GPUs:
> 1- gstvaapidecode:
>     HW decoding and dmabuf export with nouveau driver on Nvidia GPU.
> 2- glimagesink:
>     EGLImage imports dmabuf on Intel GPU.
>
> Note that tiling is working if 1 and 2 are done on the same GPU.
> So it is up to the application to set or not the flag:
> VA_SURFACE_EXTBUF_DESC_ENABLE_TILING
>
> Signed-off-by: Julien Isorce <j.isorce at samsung.com>

NAK, it won't be possible to use the resulting video buffer with 
hardware decoding on AMD hardware.

Please add a bind flag to struct pipe_video_buffer instead so that we 
can specify if linear layout is requested or not.

This way the hardware driver can still reject the request if this would 
result in a surface which can't be decoded to.

Regards,
Christian.

> ---
>   src/gallium/state_trackers/va/surface.c | 60 ++++++++++++++++++++++++++++++++-
>   1 file changed, 59 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
> index 8a6a397..b04ced4 100644
> --- a/src/gallium/state_trackers/va/surface.c
> +++ b/src/gallium/state_trackers/va/surface.c
> @@ -507,7 +507,9 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
>      int i;
>      int memory_type;
>      int expected_fourcc;
> +   int linear_layout;
>      VAStatus vaStatus;
> +   const enum pipe_format *resource_formats;
>   
>      if (!ctx)
>         return VA_STATUS_ERROR_INVALID_CONTEXT;
> @@ -529,6 +531,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
>      memory_attibute = NULL;
>      memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
>      expected_fourcc = 0;
> +   resource_formats = NULL;
>   
>      for (i = 0; i < num_attribs && attrib_list; i++) {
>         if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
> @@ -569,8 +572,27 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
>         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
>      }
>   
> +   /* The application will clear the TILING flag when the surface is
> +    * intended to be exported as dmabuf. */
> +   linear_layout = memory_attibute &&
> +      !(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING);
> +
>      switch (memory_type) {
>      case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
> +      if (linear_layout) {
> +         switch (expected_fourcc) {
> +            case VA_FOURCC_RGBA:
> +            case VA_FOURCC_RGBX:
> +            case VA_FOURCC_BGRA:
> +            case VA_FOURCC_BGRX:
> +               if (memory_attibute->num_planes != 1)
> +                  return VA_STATUS_ERROR_INVALID_PARAMETER;
> +               break;
> +            default:
> +               return VA_STATUS_ERROR_INVALID_PARAMETER;
> +         }
> +      }
> +
>         break;
>      case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
>         if (!memory_attibute)
> @@ -587,6 +609,13 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
>      if (expected_fourcc) {
>         templat.buffer_format = VaFourccToPipeFormat(expected_fourcc);
>         templat.interlaced = 0;
> +
> +      if (linear_layout) {
> +         resource_formats = vl_video_buffer_formats(pscreen,
> +                                                    templat.buffer_format);
> +         if (!resource_formats)
> +            return VA_STATUS_ERROR_INVALID_PARAMETER;
> +      }
>      } else {
>         templat.buffer_format = pscreen->get_video_param
>               (
> @@ -621,7 +650,36 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
>   
>         switch (memory_type) {
>         case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
> -         surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);
> +         if (linear_layout) {
> +            struct pipe_resource resource_template;
> +            struct pipe_resource *resources[VL_NUM_COMPONENTS];
> +            int depth = 1;
> +            int array_size = 1;
> +
> +            memset(resources, 0, sizeof(resources));
> +
> +            assert(resource_formats);
> +            vl_video_buffer_template(&resource_template, &templat,
> +                                     resource_formats[0], depth, array_size,
> +                                     PIPE_USAGE_DEFAULT, 0);
> +
> +            /* Shared because VASurfaceAttribExternalBuffers is used. */
> +            assert(memory_attibute);
> +            resource_template.bind |= PIPE_BIND_LINEAR | PIPE_BIND_SHARED;
> +
> +            resources[0] = pscreen->resource_create(pscreen,
> +                                                    &resource_template);
> +            if (!resources[0]) {
> +                FREE(surf);
> +                goto no_res;
> +            }
> +
> +            surf->buffer = vl_video_buffer_create_ex2(drv->pipe, &templat,
> +                                                      resources);
> +         } else {
> +            surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);
> +         }
> +
>            if (!surf->buffer) {
>               FREE(surf);
>               goto no_res;



More information about the mesa-dev mailing list