[Mesa-dev] [PATCH v4 4/9] st/va: implement dmabuf import for VaCreateSurfaces2

Julien Isorce j.isorce at samsung.com
Fri Oct 30 04:02:06 PDT 2015



-----Original Message-----
From: Christian K├Ânig [mailto:deathsimple at vodafone.de] 
Sent: 29 October 2015 19:24
To: Julien Isorce; mesa-dev at lists.freedesktop.org
Subject: Re: [PATCH v4 4/9] st/va: implement dmabuf import for
VaCreateSurfaces2

On 29.10.2015 18:40, Julien Isorce wrote:
> For now it is limited to RGBA, BGRA, RGBX, BGRX surfaces.
>
> Signed-off-by: Julien Isorce <j.isorce at samsung.com>
> ---
>   src/gallium/state_trackers/va/surface.c | 97
++++++++++++++++++++++++++++++++-
>   1 file changed, 96 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/state_trackers/va/surface.c 
> b/src/gallium/state_trackers/va/surface.c
> index c3c015e..c1f7182 100644
> --- a/src/gallium/state_trackers/va/surface.c
> +++ b/src/gallium/state_trackers/va/surface.c
> @@ -29,6 +29,8 @@
>   #include "pipe/p_screen.h"
>   #include "pipe/p_video_codec.h"
>   
> +#include "state_tracker/drm_driver.h"
> +
>   #include "util/u_memory.h"
>   #include "util/u_handle_table.h"
>   #include "util/u_rect.h"
> @@ -41,6 +43,8 @@
>   
>   #include "va_private.h"
>   
> +#include <va/va_drmcommon.h>
> +
>   VAStatus
>   vlVaCreateSurfaces(VADriverContextP ctx, int width, int height, int
format,
>                      int num_surfaces, VASurfaceID *surfaces) @@ 
> -368,7 +372,8 @@ vlVaQuerySurfaceAttributes(VADriverContextP ctx,
VAConfigID config,
>       attribs[i].type = VASurfaceAttribMemoryType;
>       attribs[i].value.type = VAGenericValueTypeInteger;
>       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE |
VA_SURFACE_ATTRIB_SETTABLE;
> -    attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
> +    attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
> +        VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
>       i++;
>   
>       attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
> @@ -402,6 +407,83 @@ vlVaQuerySurfaceAttributes(VADriverContextP ctx,
VAConfigID config,
>       return VA_STATUS_SUCCESS;
>   }
>   
> +static VAStatus
> +suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface,
> +                            VASurfaceAttribExternalBuffers
*memory_attibute,
> +                            int index, VASurfaceID *surfaces,
> +                            struct pipe_video_buffer *templat) {
> +    vlVaDriver *drv;
> +    struct pipe_screen *pscreen;
> +    struct pipe_resource *resource;
> +    struct pipe_resource res_templ;
> +    struct winsys_handle whandle;
> +    struct pipe_resource *resources[VL_NUM_COMPONENTS];
> +
> +    if (!ctx)
> +        return VA_STATUS_ERROR_INVALID_PARAMETER;
> +
> +    pscreen = VL_VA_PSCREEN(ctx);
> +    drv = VL_VA_DRIVER(ctx);
> +
> +    if (!memory_attibute || !memory_attibute->buffers ||
> +        index > memory_attibute->num_buffers)
> +        return VA_STATUS_ERROR_INVALID_PARAMETER;
> +
> +    if (surface->templat.width != memory_attibute->width ||
> +        surface->templat.height != memory_attibute->height ||
> +        memory_attibute->num_planes < 1)
> +        return VA_STATUS_ERROR_INVALID_PARAMETER;
> +
> +    switch (memory_attibute->pixel_format) {
> +    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;
> +    }
> +
> +    memset(&res_templ, 0, sizeof(res_templ));
> +    res_templ.target = PIPE_TEXTURE_2D;
> +    res_templ.last_level = 0;
> +    res_templ.depth0 = 1;
> +    res_templ.array_size = 1;
> +    res_templ.width0 = memory_attibute->width;
> +    res_templ.height0 = memory_attibute->height;
> +    res_templ.format = surface->templat.buffer_format;
> +    res_templ.bind = PIPE_BIND_SAMPLER_VIEW;
> +    res_templ.usage = PIPE_USAGE_DEFAULT;
> +
> +    memset(&whandle, 0, sizeof(struct winsys_handle));
> +    whandle.type = DRM_API_HANDLE_TYPE_FD;
> +    whandle.handle = memory_attibute->buffers[index];
> +    whandle.stride = memory_attibute->pitches[index];
> +
> +    resource = pscreen->resource_from_handle(pscreen, &res_templ, 
> + &whandle);
> +
> +    if (!resource)
> +       return VA_STATUS_ERROR_ALLOCATION_FAILED;
> +
> +    memset(resources, 0, sizeof resources);
> +    resources[0] = resource;
> +
> +    surface->buffer = vl_video_buffer_create_ex2(drv->pipe, templat, 
> + resources);

>>That's a bit tricky. At least the memory layout UVD uses isn't shareable
using DMA-buf.
>>So after importing this buffer you can't use it as a decoding target for
video decoding.
>>So you should probably have a flag or something that video buffers created
like this can't be used for decoding frames.

Ah ok. Well for now it is limited to import RGBs formats, see the switch
above the lines you pointed at. So it won't be NV12 so it won't be possible
to use it as decoding target for video decoding.
If you have something in mind about how to add that flag, let me know or
feel free to add it. Otherwise I think it is fine for the reason above.
Thx
Julien

>>Regards,
>>Christian.

> +    if (!surface->buffer)
> +        return VA_STATUS_ERROR_ALLOCATION_FAILED;
> +
> +    util_dynarray_init(&surface->subpics);
> +    surfaces[index] = handle_table_add(drv->htab, surface);
> +
> +    if (!surfaces[index])
> +      return VA_STATUS_ERROR_ALLOCATION_FAILED;
> +
> +    return VA_STATUS_SUCCESS;
> +}
> +
>   VAStatus
>   vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
>                       unsigned int width, unsigned int height, @@ 
> -415,6 +497,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int
format,
>       int i;
>       int memory_type;
>       int expected_fourcc;
> +    VAStatus vaStatus;
>   
>       if (!ctx)
>          return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -453,6 +536,7 @@ 
> vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
>   
>               switch (attrib_list[i].value.value.i) {
>                   case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
> +                case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
>                      memory_type = attrib_list[i].value.value.i;
>                      break;
>                   default:
> @@ -479,6 +563,12 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned
int format,
>       switch (memory_type) {
>           case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
>               break;
> +        case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
> +            if (!memory_attibute)
> +               return VA_STATUS_ERROR_INVALID_PARAMETER;
> +
> +            expected_fourcc = memory_attibute->pixel_format;
> +            break;
>           default:
>               assert(0);
>       }
> @@ -528,6 +618,11 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned
int format,
>                   util_dynarray_init(&surf->subpics);
>                   surfaces[i] = handle_table_add(drv->htab, surf);
>                   break;
> +            case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
> +                vaStatus = suface_from_external_memory(ctx, surf,
memory_attibute, i, surfaces, &templat);
> +                if (vaStatus != VA_STATUS_SUCCESS)
> +                  goto no_res;
> +                break;
>               default:
>                   assert(0);
>           }



More information about the mesa-dev mailing list