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:
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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.
|
||||
*
|
||||
|
Reference in New Issue
Block a user