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 <sivileri@microsoft.com>
Reviewed-by: Leo Liu <leo.liu@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25296>
This commit is contained in:
David Rosca
2023-09-19 10:53:21 +02:00
committed by Marge Bot
parent d6b2a624a1
commit 24ff1062b1
4 changed files with 32 additions and 3 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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.
*