frontends/va: Only export one handle for contiguous planes

If the driver stores all planes contiguously in memory, only one BO
needs to be exported from vaExportSurfaceHandle. This is required
for Chromium's VaapiVideoDecoder to work on radeonsi and r600.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26165>
This commit is contained in:
Hannes Mann
2023-11-20 23:17:31 +01:00
committed by Marge Bot
parent 4f4c9ff68a
commit f419a8be90
+41 -23
View File
@@ -1643,8 +1643,11 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
#else
VADRMPRIMESurfaceDescriptor *desc = descriptor;
desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
desc->width = surf->templat.width;
desc->width = surf->templat.width;
desc->height = surf->templat.height;
desc->num_objects = 0;
bool supports_contiguous_planes = screen->resource_get_info && surf->buffer->contiguous_planes;
for (p = 0; p < ARRAY_SIZE(desc->objects); p++) {
struct winsys_handle whandle;
@@ -1662,37 +1665,52 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
goto fail;
}
memset(&whandle, 0, sizeof(whandle));
whandle.type = WINSYS_HANDLE_TYPE_FD;
/* If the driver stores all planes contiguously in memory, only one
* handle needs to be exported. resource_get_info is used to obtain
* pitch and offset for each layer. */
if (!desc->num_objects || !supports_contiguous_planes) {
memset(&whandle, 0, sizeof(whandle));
whandle.type = WINSYS_HANDLE_TYPE_FD;
if (!screen->resource_get_handle(screen, drv->pipe, resource,
&whandle, usage)) {
ret = VA_STATUS_ERROR_INVALID_SURFACE;
goto fail;
if (!screen->resource_get_handle(screen, drv->pipe, resource,
&whandle, usage)) {
ret = VA_STATUS_ERROR_INVALID_SURFACE;
goto fail;
}
desc->objects[desc->num_objects].fd = (int) whandle.handle;
/* As per VADRMPRIMESurfaceDescriptor documentation, size must be the
* "Total size of this object (may include regions which are not part
* of the surface)."" */
desc->objects[desc->num_objects].size = (uint32_t) whandle.size;
desc->objects[desc->num_objects].drm_format_modifier = whandle.modifier;
desc->num_objects++;
}
desc->objects[p].fd = (int)whandle.handle;
/* As per VADRMPRIMESurfaceDescriptor documentation, size must be the
* "Total size of this object (may include regions which are not part
* of the surface)."" */
desc->objects[p].size = (uint32_t) whandle.size;
desc->objects[p].drm_format_modifier = whandle.modifier;
if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS) {
desc->layers[0].object_index[p] = p;
desc->layers[0].offset[p] = whandle.offset;
desc->layers[0].pitch[p] = whandle.stride;
desc->layers[0].object_index[p] = desc->num_objects - 1;
if (supports_contiguous_planes) {
screen->resource_get_info(screen, resource, &desc->layers[0].pitch[p], &desc->layers[0].offset[p]);
} else {
desc->layers[0].pitch[p] = whandle.stride;
desc->layers[0].offset[p] = whandle.offset;
}
} else {
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->layers[p].object_index[0] = desc->num_objects - 1;
if (supports_contiguous_planes) {
screen->resource_get_info(screen, resource, &desc->layers[p].pitch[0], &desc->layers[p].offset[0]);
} else {
desc->layers[p].pitch[0] = whandle.stride;
desc->layers[p].offset[0] = whandle.offset;
}
}
}
desc->num_objects = p;
if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS) {
uint32_t drm_format = pipe_format_to_drm_format(surf->buffer->buffer_format);
if (drm_format == DRM_FORMAT_INVALID) {
@@ -1714,7 +1732,7 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
fail:
#ifndef _WIN32
for (i = 0; i < p; i++)
for (i = 0; i < desc->num_objects; i++)
close(desc->objects[i].fd);
#else
if(whandle.handle)