mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-11 20:00:38 +01:00
st/va: Implement vaExportSurfaceHandle()
This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs. In particular, this allows export of NV12 and
P010 surfaces.
v2: Convert surfaces to progressive before exporting them (Christian).
v3: Set destination rectangle to match source when converting (Leo).
Add guards to allow building with libva1.
Signed-off-by: Mark Thompson <sw@jkqxz.net>
Acked-by: Christian König <christian.koenig@amd.com>
Acked-and-Tested-by: Leo Liu <leo.liu@amd.com>
This commit is contained in:
parent
52b73caaf4
commit
c4ed39f85b
3 changed files with 153 additions and 1 deletions
|
|
@ -88,7 +88,10 @@ static struct VADriverVTable vtable =
|
|||
&vlVaCreateSurfaces2,
|
||||
&vlVaQuerySurfaceAttributes,
|
||||
&vlVaAcquireBufferHandle,
|
||||
&vlVaReleaseBufferHandle
|
||||
&vlVaReleaseBufferHandle,
|
||||
#if VA_CHECK_VERSION(1, 0, 0)
|
||||
&vlVaExportSurfaceHandle,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct VADriverVTableVPP vtable_vpp =
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "va_private.h"
|
||||
|
||||
#include <va/va_drmcommon.h>
|
||||
#include <drm-uapi/drm_fourcc.h>
|
||||
|
||||
static const enum pipe_format vpp_surface_formats[] = {
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
|
||||
|
|
@ -901,3 +902,150 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, VAContextID context,
|
|||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if VA_CHECK_VERSION(1, 0, 0)
|
||||
VAStatus
|
||||
vlVaExportSurfaceHandle(VADriverContextP ctx,
|
||||
VASurfaceID surface_id,
|
||||
uint32_t mem_type,
|
||||
uint32_t flags,
|
||||
void *descriptor)
|
||||
{
|
||||
vlVaDriver *drv;
|
||||
vlVaSurface *surf;
|
||||
struct pipe_surface **surfaces;
|
||||
struct pipe_screen *screen;
|
||||
VAStatus ret;
|
||||
unsigned int usage;
|
||||
int i, p;
|
||||
|
||||
VADRMPRIMESurfaceDescriptor *desc = descriptor;
|
||||
|
||||
if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
|
||||
return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
|
||||
if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
|
||||
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||
|
||||
drv = VL_VA_DRIVER(ctx);
|
||||
screen = VL_VA_PSCREEN(ctx);
|
||||
mtx_lock(&drv->mutex);
|
||||
|
||||
surf = handle_table_get(drv->htab, surface_id);
|
||||
if (!surf || !surf->buffer) {
|
||||
mtx_unlock(&drv->mutex);
|
||||
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||
}
|
||||
|
||||
if (surf->buffer->interlaced) {
|
||||
struct pipe_video_buffer *interlaced = surf->buffer;
|
||||
struct u_rect src_rect, dst_rect;
|
||||
|
||||
surf->templat.interlaced = false;
|
||||
|
||||
ret = vlVaHandleSurfaceAllocate(drv, surf, &surf->templat);
|
||||
if (ret != VA_STATUS_SUCCESS) {
|
||||
mtx_unlock(&drv->mutex);
|
||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
src_rect.x0 = dst_rect.x0 = 0;
|
||||
src_rect.y0 = dst_rect.y0 = 0;
|
||||
src_rect.x1 = dst_rect.x1 = surf->templat.width;
|
||||
src_rect.y1 = dst_rect.y1 = surf->templat.height;
|
||||
|
||||
vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
|
||||
interlaced, surf->buffer,
|
||||
&src_rect, &dst_rect,
|
||||
VL_COMPOSITOR_WEAVE);
|
||||
|
||||
interlaced->destroy(interlaced);
|
||||
}
|
||||
|
||||
surfaces = surf->buffer->get_surfaces(surf->buffer);
|
||||
|
||||
usage = 0;
|
||||
if (flags & VA_EXPORT_SURFACE_READ_ONLY)
|
||||
usage |= PIPE_HANDLE_USAGE_READ;
|
||||
if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
|
||||
usage |= PIPE_HANDLE_USAGE_WRITE;
|
||||
|
||||
desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
|
||||
desc->width = surf->buffer->width;
|
||||
desc->height = surf->buffer->height;
|
||||
|
||||
for (p = 0; p < VL_MAX_SURFACES; p++) {
|
||||
struct winsys_handle whandle;
|
||||
struct pipe_resource *resource;
|
||||
uint32_t drm_format;
|
||||
|
||||
if (!surfaces[p])
|
||||
break;
|
||||
|
||||
resource = surfaces[p]->texture;
|
||||
|
||||
switch (resource->format) {
|
||||
case PIPE_FORMAT_R8_UNORM:
|
||||
drm_format = DRM_FORMAT_R8;
|
||||
break;
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
drm_format = DRM_FORMAT_GR88;
|
||||
break;
|
||||
case PIPE_FORMAT_R16_UNORM:
|
||||
drm_format = DRM_FORMAT_R16;
|
||||
break;
|
||||
case PIPE_FORMAT_R16G16_UNORM:
|
||||
drm_format = DRM_FORMAT_GR1616;
|
||||
break;
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
drm_format = DRM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
drm_format = DRM_FORMAT_ABGR8888;
|
||||
break;
|
||||
case PIPE_FORMAT_B8G8R8X8_UNORM:
|
||||
drm_format = DRM_FORMAT_XRGB8888;
|
||||
break;
|
||||
case PIPE_FORMAT_R8G8B8X8_UNORM:
|
||||
drm_format = DRM_FORMAT_XBGR8888;
|
||||
break;
|
||||
default:
|
||||
ret = VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memset(&whandle, 0, sizeof(whandle));
|
||||
whandle.type = DRM_API_HANDLE_TYPE_FD;
|
||||
|
||||
if (!screen->resource_get_handle(screen, drv->pipe, resource,
|
||||
&whandle, usage)) {
|
||||
ret = VA_STATUS_ERROR_INVALID_SURFACE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
desc->objects[p].fd = (int)whandle.handle;
|
||||
desc->objects[p].size = 0;
|
||||
desc->objects[p].drm_format_modifier = whandle.modifier;
|
||||
|
||||
desc->layers[p].drm_format = drm_format;
|
||||
desc->layers[p].num_planes = 1;
|
||||
desc->layers[p].object_index[0] = p;
|
||||
desc->layers[p].offset[0] = whandle.offset;
|
||||
desc->layers[p].pitch[0] = whandle.stride;
|
||||
}
|
||||
|
||||
desc->num_objects = p;
|
||||
desc->num_layers = p;
|
||||
|
||||
mtx_unlock(&drv->mutex);
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < p; i++)
|
||||
close(desc->objects[i].fd);
|
||||
|
||||
mtx_unlock(&drv->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -394,6 +394,7 @@ VAStatus vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config, VAS
|
|||
|
||||
VAStatus vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, VABufferInfo *out_buf_info);
|
||||
VAStatus vlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id);
|
||||
VAStatus vlVaExportSurfaceHandle(VADriverContextP ctx, VASurfaceID surface_id, uint32_t mem_type, uint32_t flags, void *descriptor);
|
||||
|
||||
VAStatus vlVaQueryVideoProcFilters(VADriverContextP ctx, VAContextID context, VAProcFilterType *filters,
|
||||
unsigned int *num_filters);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue