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;

Reply via email to