frontends/va: Unlock driver mutex for SyncSurface/Buffer fence wait

Only keep context mutex locked while waiting for fence.

This fixes issue with multi-threaded use of VAAPI where SyncSurface
and SyncBuffer would block all contexts, even those used in different
threads. The issue exists for all API calls, however in most cases this
is not a big deal as most calls will return fast, but sync is expected
to take up to tens of ms.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33165>
This commit is contained in:
David Rosca
2024-12-27 14:14:23 +01:00
committed by Marge Bot
parent d5c1d2faa8
commit 8357ef588f
2 changed files with 10 additions and 23 deletions
+5 -9
View File
@@ -555,31 +555,27 @@ vlVaSyncBuffer(VADriverContextP ctx, VABufferID buf_id, uint64_t timeout_ns)
mtx_lock(&drv->mutex);
buf = handle_table_get(drv->htab, buf_id);
if (!buf) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
}
/* No outstanding operation: nothing to do. */
if (!buf->fence) {
/* No outstanding operation: nothing to do. */
mtx_unlock(&drv->mutex);
return VA_STATUS_SUCCESS;
}
context = buf->ctx;
if (!context) {
if (!context || !context->decoder) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_CONTEXT;
}
if (!context->decoder) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
}
int ret = context->decoder->fence_wait(context->decoder, buf->fence, timeout_ns);
mtx_lock(&context->mutex);
mtx_unlock(&drv->mutex);
int ret = context->decoder->fence_wait(context->decoder, buf->fence, timeout_ns);
mtx_unlock(&context->mutex);
return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT;
}
#endif
+5 -14
View File
@@ -187,30 +187,21 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo
pscreen->fence_reference(pscreen, &surf->pipe_fence, NULL);
}
/* This is checked before getting the context below as
* surf->ctx is only set in begin_frame
* and not when the surface is created
* Some apps try to sync/map the surface right after creation and
* would get VA_STATUS_ERROR_INVALID_CONTEXT
*/
/* No outstanding operation: nothing to do. */
if (!surf->fence) {
// No outstanding encode/decode operation: nothing to do.
mtx_unlock(&drv->mutex);
return VA_STATUS_SUCCESS;
}
if (!context) {
if (!context || !context->decoder) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_CONTEXT;
}
if (!context->decoder) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
}
int ret = context->decoder->fence_wait(context->decoder, fence, timeout_ns);
mtx_lock(&context->mutex);
mtx_unlock(&drv->mutex);
int ret = context->decoder->fence_wait(context->decoder, fence, timeout_ns);
mtx_unlock(&context->mutex);
return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT;
}