[Mesa-dev] [PATCH 5/7] st/va: implement dmabuf import for VaCreateSurfaces2
Julien Isorce
julien.isorce at gmail.com
Fri Oct 16 16:14:24 PDT 2015
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 | 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
More information about the mesa-dev
mailing list