For now it is limited to RGBA, BGRA, RGBX, BGRX surfaces. Signed-off-by: Julien Isorce <j.iso...@samsung.com> --- src/gallium/state_trackers/va/surface.c | 90 +++++++++++++++++++++++++++++- src/gallium/state_trackers/va/va_private.h | 1 + 2 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index be435cb..eb5b8ca 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -376,7 +376,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; @@ -410,6 +411,82 @@ vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config, return vaStatus; } +static VAStatus +suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface, + VASurfaceAttribExternalBuffers *memory_attibute, + int index, VASurfaceID *surfaces, + struct pipe_video_buffer *templat) +{ + vlVaDriver *drv = NULL; + struct pipe_screen *pscreen = NULL; + struct pipe_resource *resource = NULL; + 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); + 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, @@ -450,6 +527,9 @@ 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:{ return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;} } @@ -477,6 +557,9 @@ 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: + expected_fourcc = memory_attibute->pixel_format; + break; default: assert(0); } @@ -522,6 +605,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); } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index e98f64f..2cdd787 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -33,6 +33,7 @@ #include <va/va.h> #include <va/va_backend.h> +#include <va/va_drmcommon.h> #include "pipe/p_video_enums.h" #include "pipe/p_video_codec.h" -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev