Module: Mesa Branch: main Commit: b5fa9f992da7618a9fb08605b953b2051cf63e2d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b5fa9f992da7618a9fb08605b953b2051cf63e2d
Author: David Rosca <[email protected]> Date: Sat Jul 15 14:46:53 2023 +0200 frontends/va: Skip processing buffers already converted with EFC Since the EFC conversion reallocates the dst buffer with new format, any subsequent VA postproc calls on the same surface will fall back to vl_compositor conversion. This is the case in ffmpeg where the postproc filter output buffers are reused instead of allocated for each frame. Reviewed-by: Ruijing Dong <[email protected]> Reviewed-by: Leo Liu <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24170> --- src/gallium/frontends/va/postproc.c | 46 ++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/gallium/frontends/va/postproc.c b/src/gallium/frontends/va/postproc.c index 5a4ad0fb994..ccb290f2d37 100644 --- a/src/gallium/frontends/va/postproc.c +++ b/src/gallium/frontends/va/postproc.c @@ -368,6 +368,27 @@ vlVaApplyDeint(vlVaDriver *drv, vlVaContext *context, return context->deint->video_buffer; } +static bool can_convert_with_efc(vlVaSurface *src, vlVaSurface *dst) +{ + enum pipe_format src_format, dst_format; + + if (src->buffer->interlaced) + return false; + + src_format = src->buffer->buffer_format; + + if (src_format != PIPE_FORMAT_B8G8R8A8_UNORM && + src_format != PIPE_FORMAT_R8G8B8A8_UNORM && + src_format != PIPE_FORMAT_B8G8R8X8_UNORM && + src_format != PIPE_FORMAT_R8G8B8X8_UNORM) + return false; + + dst_format = dst->encoder_format != PIPE_FORMAT_NONE ? + dst->encoder_format : dst->buffer->buffer_format; + + return dst_format == PIPE_FORMAT_NV12; +} + VAStatus vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -400,28 +421,25 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex pscreen = drv->vscreen->pscreen; - if (src_surface->buffer->buffer_format != dst_surface->buffer->buffer_format && - !src_surface->buffer->interlaced && - (dst_surface->buffer->buffer_format == PIPE_FORMAT_NV12 || - dst_surface->buffer->buffer_format == PIPE_FORMAT_P010 || - dst_surface->buffer->buffer_format == PIPE_FORMAT_P016) && + if (can_convert_with_efc(src_surface, dst_surface) && pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_EFC_SUPPORTED)) { - // EFC will convert the buffer to a format the encoder accepts - dst_surface->encoder_format = dst_surface->buffer->buffer_format; + vlVaSurface *surf = dst_surface; - vlVaSurface *surf; + // EFC will convert the buffer to a format the encoder accepts + if (src_surface->buffer->buffer_format != surf->buffer->buffer_format) { + surf->encoder_format = surf->buffer->buffer_format; - surf = handle_table_get(drv->htab, context->target_id); - surf->templat.interlaced = src_surface->templat.interlaced; - surf->templat.buffer_format = src_surface->templat.buffer_format; - surf->buffer->destroy(surf->buffer); + surf->templat.interlaced = src_surface->templat.interlaced; + surf->templat.buffer_format = src_surface->templat.buffer_format; + surf->buffer->destroy(surf->buffer); - if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) - return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } pipe_resource_reference(&(((struct vl_video_buffer *)(surf->buffer))->resources[0]), ((struct vl_video_buffer *)(src_surface->buffer))->resources[0]); context->target = surf->buffer;
