frontends/va: Implement sync buffer/surface timeout for encode feedback

Same as processing/decode, the driver will assign fence to
pipe_picture_desc::fence and frontend will wait on it with
get_feedback_fence.

Reviewed-By: Sil Vilerino <sivileri@microsoft.com>
Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30780>
This commit is contained in:
David Rosca
2024-08-22 16:23:53 +02:00
committed by Marge Bot
parent 6d69748542
commit 96fe9fde3f
5 changed files with 20 additions and 21 deletions

View File

@@ -559,13 +559,6 @@ vlVaSyncBuffer(VADriverContextP ctx, VABufferID buf_id, uint64_t timeout_ns)
PIPE_VIDEO_CAP_ENC_SUPPORTS_ASYNC_OPERATION))
return VA_STATUS_ERROR_UNIMPLEMENTED;
/* vaSyncBuffer spec states that "If timeout is zero, the function returns immediately." */
if (timeout_ns == 0)
return VA_STATUS_ERROR_TIMEDOUT;
if (timeout_ns != VA_TIMEOUT_INFINITE)
return VA_STATUS_ERROR_UNIMPLEMENTED;
mtx_lock(&drv->mutex);
buf = handle_table_get(drv->htab, buf_id);
@@ -589,6 +582,11 @@ vlVaSyncBuffer(VADriverContextP ctx, VABufferID buf_id, uint64_t timeout_ns)
vlVaSurface* surf = handle_table_get(drv->htab, buf->associated_encode_input_surf);
if ((buf->feedback) && (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)) {
if (surf && context->decoder->get_feedback_fence &&
!context->decoder->get_feedback_fence(context->decoder, surf->fence, timeout_ns)) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_TIMEDOUT;
}
context->decoder->get_feedback(context->decoder, buf->feedback, &(buf->coded_size), &(buf->extended_metadata));
buf->feedback = NULL;
/* Also mark the associated render target (encode source texture) surface as done

View File

@@ -1383,12 +1383,6 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
}
}
if (context->decoder->get_feedback_fence &&
!context->decoder->get_feedback_fence(context->decoder, feedback)) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
}
/* Update frame_num disregarding PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME check above */
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
if ((u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC)

View File

@@ -226,6 +226,11 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo
}
}
}
if (context->decoder->get_feedback_fence &&
!context->decoder->get_feedback_fence(context->decoder, surf->fence, timeout_ns)) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_TIMEDOUT;
}
context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size), &(surf->coded_buf->extended_metadata));
surf->feedback = NULL;
surf->coded_buf->feedback = NULL;

View File

@@ -152,16 +152,18 @@ struct pipe_video_codec
uint64_t timeout);
/**
* Gets a weak reference to a feedback fence.
* Get feedback fence.
*
* Can be used to wait on the pipe_fence_handle directly instead
* of waiting on the get_feedback blocking call.
* Can be used to query the status of the previous process job denoted by
* 'fence' given 'timeout'.
*
* Returns NULL if the feedback parameter does not have
* a valid in-flight submitted frame
* A pointer to a fence pointer can be passed to the codecs before the
* end_frame vfunc and the codec should then be responsible for allocating a
* fence on command stream submission.
*/
struct pipe_fence_handle* (*get_feedback_fence)(struct pipe_video_codec *codec,
void *feedback);
int (*get_feedback_fence)(struct pipe_video_codec *codec,
struct pipe_fence_handle *fence,
uint64_t timeout);
/**
* Destroy fence.

View File

@@ -203,7 +203,7 @@ struct pipe_picture_desc
enum pipe_format output_format;
/* Flush flags for pipe_video_codec::end_frame */
unsigned flush_flags;
/* A fence used on PIPE_VIDEO_ENTRYPOINT_DECODE/PROCESSING to signal job completion */
/* A fence for pipe_video_codec::end_frame to signal job completion */
struct pipe_fence_handle **fence;
unsigned packed_headers;
};