From 24ff1062b1df808c2ce44fb7080cb0237476c741 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Tue, 19 Sep 2023 10:53:21 +0200 Subject: [PATCH] frontends/va: Destroy fences when destroying surface or context It is valid to destroy VASurface after destroying VAContext, so we need to destroy fences of all surfaces that are currently being tracked by a context when deleting this context. Reviewed-by: Sil Vilerino Reviewed-by: Leo Liu Part-of: --- src/gallium/frontends/va/context.c | 4 ++++ src/gallium/frontends/va/picture.c | 23 ++++++++++++++++++++--- src/gallium/frontends/va/surface.c | 2 ++ src/gallium/include/pipe/p_video_codec.h | 6 ++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/gallium/frontends/va/context.c b/src/gallium/frontends/va/context.c index adb32703f28..b206d2a647d 100644 --- a/src/gallium/frontends/va/context.c +++ b/src/gallium/frontends/va/context.c @@ -400,6 +400,10 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id) vlVaSurface *surf = (vlVaSurface *)entry->key; assert(surf->ctx == context); surf->ctx = NULL; + if (surf->fence && context->decoder && context->decoder->destroy_fence) { + context->decoder->destroy_fence(context->decoder, surf->fence); + surf->fence = NULL; + } } _mesa_set_destroy(context->surfaces, NULL); diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index 952560bb391..4fc6eeb7ff3 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -39,7 +39,7 @@ #include "va_private.h" static void -vlVaSetSurfaceContext(vlVaSurface *surf, vlVaContext *context) +vlVaSetSurfaceContext(vlVaDriver *drv, vlVaSurface *surf, vlVaContext *context) { if (surf->ctx == context) return; @@ -47,6 +47,23 @@ vlVaSetSurfaceContext(vlVaSurface *surf, vlVaContext *context) if (surf->ctx) { assert(_mesa_set_search(surf->ctx->surfaces, surf)); _mesa_set_remove_key(surf->ctx->surfaces, surf); + + /* Only drivers supporting PIPE_VIDEO_ENTRYPOINT_PROCESSING will create + * decoder for postproc context and thus be able to wait on and destroy + * the surface fence. On other drivers we need to destroy the fence here + * otherwise vaQuerySurfaceStatus/vaSyncSurface will fail and we'll also + * potentially leak the fence. + */ + if (surf->fence && !context->decoder && + context->templat.entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING && + surf->ctx->decoder && surf->ctx->decoder->destroy_fence && + !drv->pipe->screen->get_video_param(drv->pipe->screen, + PIPE_VIDEO_PROFILE_UNKNOWN, + PIPE_VIDEO_ENTRYPOINT_PROCESSING, + PIPE_VIDEO_CAP_SUPPORTED)) { + surf->ctx->decoder->destroy_fence(surf->ctx->decoder, surf->fence); + surf->fence = NULL; + } } surf->ctx = context; @@ -85,7 +102,7 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_ERROR_INVALID_SURFACE; context->target_id = render_target; - vlVaSetSurfaceContext(surf, context); + vlVaSetSurfaceContext(drv, surf, context); context->target = surf->buffer; context->mjpeg.sampling_factor = 0; @@ -993,7 +1010,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) } if (apply_av1_fg) { - vlVaSetSurfaceContext(surf, context); + vlVaSetSurfaceContext(drv, surf, context); *out_target = surf->buffer; } diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c index 62f3adc3add..baddba39bbc 100644 --- a/src/gallium/frontends/va/surface.c +++ b/src/gallium/frontends/va/surface.c @@ -89,6 +89,8 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur if (surf->ctx) { assert(_mesa_set_search(surf->ctx->surfaces, surf)); _mesa_set_remove_key(surf->ctx->surfaces, surf); + if (surf->fence && surf->ctx->decoder && surf->ctx->decoder->destroy_fence) + surf->ctx->decoder->destroy_fence(surf->ctx->decoder, surf->fence); } util_dynarray_fini(&surf->subpics); FREE(surf); diff --git a/src/gallium/include/pipe/p_video_codec.h b/src/gallium/include/pipe/p_video_codec.h index 694302940d7..085dbae3f50 100644 --- a/src/gallium/include/pipe/p_video_codec.h +++ b/src/gallium/include/pipe/p_video_codec.h @@ -148,6 +148,12 @@ struct pipe_video_codec struct pipe_fence_handle *fence, uint64_t timeout); + /** + * Destroy fence. + */ + void (*destroy_fence)(struct pipe_video_codec *codec, + struct pipe_fence_handle *fence); + /** * Update target buffer address. *