From c324364f3925db190a0c013c148f901f6633151f Mon Sep 17 00:00:00 2001 From: David Rosca Date: Tue, 12 Nov 2024 16:16:43 +0100 Subject: [PATCH] frontends/va: Only use interlaced surfaces when progressive is not supported There is no good reason to use interlaced surfaces when progressive is supported and it only creates issues when exporting the surface or trying to do transcoding. This allows to remove all workarounds that handled reallocating from interlaced to progressive because a given operation would not work for interlaced. Reviewed-by: Leo Liu Part-of: --- src/gallium/frontends/va/image.c | 82 +++-------------------------- src/gallium/frontends/va/postproc.c | 46 +--------------- src/gallium/frontends/va/surface.c | 32 ++--------- 3 files changed, 14 insertions(+), 146 deletions(-) diff --git a/src/gallium/frontends/va/image.c b/src/gallium/frontends/va/image.c index 658b1093331..ed46603282e 100644 --- a/src/gallium/frontends/va/image.c +++ b/src/gallium/frontends/va/image.c @@ -259,19 +259,6 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) unsigned stride = 0; unsigned offset = 0; - /* This function is used by some programs to test for hardware decoding, but on - * AMD devices, the buffers default to interlaced, which causes this function to fail. - * Some programs expect this function to fail, while others, assume this means - * hardware acceleration is not available and give up without trying the fall-back - * vaCreateImage + vaPutImage - */ - const char *proc = util_get_process_name(); - const char *derive_interlaced_allowlist[] = { - "vlc", - "h264encode", - "hevcencode" - }; - if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -294,22 +281,15 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) } if (surf->buffer->interlaced) { - for (i = 0; i < ARRAY_SIZE(derive_interlaced_allowlist); i++) - if ((strcmp(derive_interlaced_allowlist[i], proc) == 0)) - break; + status = VA_STATUS_ERROR_OPERATION_FAILED; + goto exit_on_error; + } - if (i >= ARRAY_SIZE(derive_interlaced_allowlist) || - !screen->get_video_param(screen, PIPE_VIDEO_PROFILE_UNKNOWN, - PIPE_VIDEO_ENTRYPOINT_BITSTREAM, - PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE)) { - status = VA_STATUS_ERROR_OPERATION_FAILED; - goto exit_on_error; - } - } else if (util_format_get_num_planes(surf->buffer->buffer_format) >= 2 && - (!screen->get_video_param(screen, PIPE_VIDEO_PROFILE_UNKNOWN, - PIPE_VIDEO_ENTRYPOINT_BITSTREAM, - PIPE_VIDEO_CAP_SUPPORTS_CONTIGUOUS_PLANES_MAP) || - !surf->buffer->contiguous_planes)) { + if (util_format_get_num_planes(surf->buffer->buffer_format) >= 2 && + (!screen->get_video_param(screen, PIPE_VIDEO_PROFILE_UNKNOWN, + PIPE_VIDEO_ENTRYPOINT_BITSTREAM, + PIPE_VIDEO_CAP_SUPPORTS_CONTIGUOUS_PLANES_MAP) || + !surf->buffer->contiguous_planes)) { status = VA_STATUS_ERROR_OPERATION_FAILED; goto exit_on_error; } @@ -397,54 +377,8 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) img->offsets[1] = 0; } - if (surf->buffer->interlaced) { - struct u_rect src_rect, dst_rect; - struct pipe_video_buffer new_template; - - new_template = surf->templat; - new_template.interlaced = false; - new_buffer = drv->pipe->create_video_buffer(drv->pipe, &new_template); - - /* not all devices support non-interlaced buffers */ - if (!new_buffer) { - status = VA_STATUS_ERROR_OPERATION_FAILED; - goto exit_on_error; - } - - /* convert the interlaced to the progressive */ - src_rect.x0 = dst_rect.x0 = 0; - src_rect.x1 = dst_rect.x1 = surf->templat.width; - src_rect.y0 = dst_rect.y0 = 0; - src_rect.y1 = dst_rect.y1 = surf->templat.height; - - vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor, - surf->buffer, new_buffer, - &src_rect, &dst_rect, - VL_COMPOSITOR_WEAVE); - - /* recalculate the values now that we have a new surface */ - memset(buf_resources, 0, sizeof(buf_resources)); - new_buffer->get_resources(new_buffer, buf_resources); - if (screen->resource_get_info) { - screen->resource_get_info(screen, buf_resources[0], &img->pitches[0], - &img->offsets[0]); - if (!img->pitches[0]) - img->offsets[0] = 0; - - screen->resource_get_info(screen, buf_resources[1], &img->pitches[1], - &img->offsets[1]); - if (!img->pitches[1]) - img->offsets[1] = 0; - } - - w = align(new_buffer->width, 2); - h = align(new_buffer->height, 2); - } - img->num_planes = 2; if(screen->resource_get_info) { - /* Note this block might use h and w from the recalculated size if it entered - the interlaced branch above.*/ img->data_size = (img->pitches[0] * h) + (img->pitches[1] * h / 2); } else { /* Use stride = w as default if screen->resource_get_info was not available */ diff --git a/src/gallium/frontends/va/postproc.c b/src/gallium/frontends/va/postproc.c index 0dd01f23bfd..e65d2d36bf2 100644 --- a/src/gallium/frontends/va/postproc.c +++ b/src/gallium/frontends/va/postproc.c @@ -357,7 +357,6 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, struct pipe_surface **dst_surfaces; struct u_rect src_rect; struct u_rect dst_rect; - bool scale = false; bool grab = false; unsigned i, src_num_planes, dst_num_planes; @@ -375,29 +374,10 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, !src->interlaced) grab = true; - if ((src->width != dst->width || src->height != dst->height) && - (src->interlaced && dst->interlaced)) - scale = true; - src_surfaces = src->get_surfaces(src); if (!src_surfaces || !src_surfaces[0]) return VA_STATUS_ERROR_INVALID_SURFACE; - if (scale || (src->interlaced != dst->interlaced && dst->interlaced)) { - vlVaSurface *surf; - - surf = handle_table_get(drv->htab, context->target_id); - if (!surf) - return VA_STATUS_ERROR_INVALID_SURFACE; - surf->templat.interlaced = false; - dst->destroy(dst); - - if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) - return VA_STATUS_ERROR_ALLOCATION_FAILED; - - dst = context->target = surf->buffer; - } - dst_surfaces = dst->get_surfaces(dst); if (!dst_surfaces || !dst_surfaces[0]) return VA_STATUS_ERROR_INVALID_SURFACE; @@ -433,15 +413,6 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, return VA_STATUS_SUCCESS; } - if (src->interlaced != dst->interlaced) { - deinterlace = deinterlace ? deinterlace : VL_COMPOSITOR_WEAVE; - vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor, - src, dst, &src_rect, &dst_rect, - deinterlace); - - return VA_STATUS_SUCCESS; - } - for (i = 0; i < VL_MAX_SURFACES; ++i) { struct pipe_surface *from = src_surfaces[i]; struct pipe_blit_info blit; @@ -547,7 +518,7 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex VARectangle def_src_region, def_dst_region; const VARectangle *src_region, *dst_region; VAProcPipelineParameterBuffer *param; - struct pipe_video_buffer *src, *dst; + struct pipe_video_buffer *src; vlVaSurface *src_surface, *dst_surface; unsigned i; struct pipe_screen *pscreen; @@ -618,21 +589,6 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex } src = src_surface->buffer; - dst = dst_surface->buffer; - - /* convert the destination buffer to progressive if we're deinterlacing - otherwise we might end up deinterlacing twice */ - if (param->num_filters && dst->interlaced) { - vlVaSurface *surf; - surf = dst_surface; - surf->templat.interlaced = false; - dst->destroy(dst); - - if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) - return VA_STATUS_ERROR_ALLOCATION_FAILED; - - dst = context->target = surf->buffer; - } for (i = 0; i < param->num_filters; i++) { vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]); diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c index 505f0bde79d..34b0a30f502 100644 --- a/src/gallium/frontends/va/surface.c +++ b/src/gallium/frontends/va/surface.c @@ -1250,9 +1250,9 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, if (!modifiers) templat.interlaced = - pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, - PIPE_VIDEO_ENTRYPOINT_BITSTREAM, - PIPE_VIDEO_CAP_PREFERS_INTERLACED); + !pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, + PIPE_VIDEO_ENTRYPOINT_BITSTREAM, + PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE); #ifndef _WIN32 if (expected_fourcc != VA_FOURCC_NV12 || memory_attribute || prime_desc) @@ -1650,30 +1650,8 @@ vlVaExportSurfaceHandle(VADriverContextP ctx, } 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, NULL, 0); - 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); - if (interlaced->codec && interlaced->codec->update_decoder_target) - interlaced->codec->update_decoder_target(interlaced->codec, interlaced, surf->buffer); - - interlaced->destroy(interlaced); + mtx_unlock(&drv->mutex); + return VA_STATUS_ERROR_INVALID_SURFACE; } surfaces = surf->buffer->get_surfaces(surf->buffer);