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