surface: Add ExportSurfaceHandle support for dma-buf export
This is the latest version of dma-buf export, that does support specifying DRM modifiers. Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
This commit is contained in:
@@ -88,6 +88,7 @@ VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
|||||||
vtable->vaCreateSurfaces = RequestCreateSurfaces;
|
vtable->vaCreateSurfaces = RequestCreateSurfaces;
|
||||||
vtable->vaCreateSurfaces2 = RequestCreateSurfaces2;
|
vtable->vaCreateSurfaces2 = RequestCreateSurfaces2;
|
||||||
vtable->vaDestroySurfaces = RequestDestroySurfaces;
|
vtable->vaDestroySurfaces = RequestDestroySurfaces;
|
||||||
|
vtable->vaExportSurfaceHandle = RequestExportSurfaceHandle;
|
||||||
vtable->vaCreateContext = RequestCreateContext;
|
vtable->vaCreateContext = RequestCreateContext;
|
||||||
vtable->vaDestroyContext = RequestDestroyContext;
|
vtable->vaDestroyContext = RequestDestroyContext;
|
||||||
vtable->vaCreateBuffer = RequestCreateBuffer;
|
vtable->vaCreateBuffer = RequestCreateBuffer;
|
||||||
|
|||||||
@@ -31,10 +31,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <va/va_drmcommon.h>
|
||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
#include "media.h"
|
#include "media.h"
|
||||||
@@ -335,3 +338,96 @@ VAStatus RequestUnlockSurface(VADriverContextP context, VASurfaceID surface_id)
|
|||||||
{
|
{
|
||||||
return VA_STATUS_ERROR_UNIMPLEMENTED;
|
return VA_STATUS_ERROR_UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VAStatus RequestExportSurfaceHandle(VADriverContextP context,
|
||||||
|
VASurfaceID surface_id, uint32_t mem_type,
|
||||||
|
uint32_t flags, void *descriptor)
|
||||||
|
{
|
||||||
|
struct request_data *driver_data = context->pDriverData;
|
||||||
|
VADRMPRIMESurfaceDescriptor *surface_descriptor = descriptor;
|
||||||
|
struct object_surface *surface_object;
|
||||||
|
struct video_format *video_format;
|
||||||
|
int *export_fds = NULL;
|
||||||
|
unsigned int export_fds_count;
|
||||||
|
unsigned int planes_count;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int i;
|
||||||
|
VAStatus status;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
|
||||||
|
return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
|
||||||
|
|
||||||
|
surface_object = SURFACE(driver_data, surface_id);
|
||||||
|
if (surface_object == NULL)
|
||||||
|
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
|
||||||
|
export_fds_count = surface_object->destination_buffers_count;
|
||||||
|
export_fds = malloc(export_fds_count * sizeof(*export_fds));
|
||||||
|
|
||||||
|
rc = v4l2_export_buffer(driver_data->video_fd,
|
||||||
|
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
||||||
|
surface_object->destination_index, O_RDONLY,
|
||||||
|
export_fds, export_fds_count);
|
||||||
|
if (rc < 0) {
|
||||||
|
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
planes_count = surface_object->destination_planes_count;
|
||||||
|
|
||||||
|
video_format = video_format_find(driver_data->tiled_format);
|
||||||
|
if (video_format == NULL) {
|
||||||
|
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_descriptor->fourcc = VA_FOURCC_NV12;
|
||||||
|
surface_descriptor->width = surface_object->width;
|
||||||
|
surface_descriptor->height = surface_object->height;
|
||||||
|
surface_descriptor->num_objects = export_fds_count;
|
||||||
|
|
||||||
|
if (export_fds_count == 1) {
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < planes_count; i++)
|
||||||
|
size += surface_object->destination_sizes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < export_fds_count; i++) {
|
||||||
|
surface_descriptor->objects[i].drm_format_modifier =
|
||||||
|
video_format->drm_modifier;
|
||||||
|
surface_descriptor->objects[i].fd = export_fds[i];
|
||||||
|
surface_descriptor->objects[i].size = export_fds_count == 1 ?
|
||||||
|
size :
|
||||||
|
surface_object->destination_sizes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_descriptor->num_layers = 1;
|
||||||
|
|
||||||
|
surface_descriptor->layers[0].drm_format = video_format->drm_format;
|
||||||
|
surface_descriptor->layers[0].num_planes = planes_count;
|
||||||
|
|
||||||
|
for (i = 0; i < planes_count; i++) {
|
||||||
|
surface_descriptor->layers[0].object_index[i] =
|
||||||
|
export_fds_count == 1 ? 0 : i;
|
||||||
|
surface_descriptor->layers[0].offset[i] =
|
||||||
|
surface_object->destination_offsets[i];
|
||||||
|
surface_descriptor->layers[0].pitch[i] =
|
||||||
|
surface_object->destination_bytesperlines[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
status = VA_STATUS_SUCCESS;
|
||||||
|
goto complete;
|
||||||
|
|
||||||
|
error:
|
||||||
|
for (i = 0; i < export_fds_count; i++)
|
||||||
|
if (export_fds[i] >= 0)
|
||||||
|
close(export_fds[i]);
|
||||||
|
|
||||||
|
complete:
|
||||||
|
if (export_fds != NULL)
|
||||||
|
free(export_fds);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,5 +105,8 @@ VAStatus RequestLockSurface(VADriverContextP context, VASurfaceID surface_id,
|
|||||||
unsigned int *chroma_v_offset,
|
unsigned int *chroma_v_offset,
|
||||||
unsigned int *buffer_name, void **buffer);
|
unsigned int *buffer_name, void **buffer);
|
||||||
VAStatus RequestUnlockSurface(VADriverContextP context, VASurfaceID surface_id);
|
VAStatus RequestUnlockSurface(VADriverContextP context, VASurfaceID surface_id);
|
||||||
|
VAStatus RequestExportSurfaceHandle(VADriverContextP context,
|
||||||
|
VASurfaceID surface_id, uint32_t mem_type,
|
||||||
|
uint32_t flags, void *descriptor);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user