From f419a8be904d9aac52186252920b30b82fdad406 Mon Sep 17 00:00:00 2001 From: Hannes Mann Date: Mon, 20 Nov 2023 23:17:31 +0100 Subject: [PATCH] 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: --- src/gallium/frontends/va/surface.c | 64 +++++++++++++++++++----------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c index 89efb42d326..dae357b9658 100644 --- a/src/gallium/frontends/va/surface.c +++ b/src/gallium/frontends/va/surface.c @@ -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)