Module: Mesa Branch: main Commit: c638e61ef5e2e7de097a9b5850eff75022330f68 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=c638e61ef5e2e7de097a9b5850eff75022330f68
Author: David Rosca <[email protected]> Date: Thu Nov 2 09:29:25 2023 +0100 frontends/va: Map decoder and postproc surfaces for reading If application requests to map surface that was most recently used as decoder or postproc target and also doesn't explicitly set the map flags (vaMapBuffer2) it's very likely the intent is to read from this surface, so we need to map it as such. This fixes regression on radeonsi where mapping NV12 surfaces for reading would fail with applications using vaDeriveImage. The reason for this is that the VA frontend doesn't allow vaDeriveImage for interlaced surfaces so the applications would use vaGetImage fallback, but radeonsi doesn't allocate NV12 surfaces as interlaced anymore. This also fixes mapping other formats surfaces (P010, RGBx, ...) for reading, which never worked before. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9935 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10048 Reviewed-by: Leo Liu <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26008> --- src/gallium/frontends/va/buffer.c | 5 +++++ src/gallium/frontends/va/image.c | 3 +++ src/gallium/frontends/va/va_private.h | 1 + 3 files changed, 9 insertions(+) diff --git a/src/gallium/frontends/va/buffer.c b/src/gallium/frontends/va/buffer.c index dd160439aa6..c1f4d9d882d 100644 --- a/src/gallium/frontends/va/buffer.c +++ b/src/gallium/frontends/va/buffer.c @@ -173,6 +173,11 @@ VAStatus vlVaMapBuffer2(VADriverContextP ctx, VABufferID buf_id, usage = PIPE_MAP_READ; else usage = PIPE_MAP_WRITE; + + /* Map decoder and postproc surfaces also for reading. */ + if (buf->derived_surface.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM || + buf->derived_surface.entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING) + usage |= PIPE_MAP_READ; } if (flags & VA_MAPBUFFER_FLAG_READ) diff --git a/src/gallium/frontends/va/image.c b/src/gallium/frontends/va/image.c index d109646d3ff..98d423f2a4d 100644 --- a/src/gallium/frontends/va/image.c +++ b/src/gallium/frontends/va/image.c @@ -435,6 +435,9 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture); img_buf->derived_image_buffer = new_buffer; + if (surf->ctx) + img_buf->derived_surface.entrypoint = surf->ctx->templat.entrypoint; + img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf); mtx_unlock(&drv->mutex); diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index 5df1bdb6d70..df80a60623c 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -316,6 +316,7 @@ typedef struct { struct { struct pipe_resource *resource; struct pipe_transfer *transfer; + enum pipe_video_entrypoint entrypoint; } derived_surface; unsigned int export_refcount; VABufferInfo export_state;
