Mesa (staging/20.0): svga, winsys/svga: Fix persistent memory discard maps

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 1 16:06:15 UTC 2020


Module: Mesa
Branch: staging/20.0
Commit: 5e85ed86eb72c45741bd3f0ae32c04e8bd54b381
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5e85ed86eb72c45741bd3f0ae32c04e8bd54b381

Author: Thomas Hellstrom <thellstrom at vmware.com>
Date:   Sat Mar 28 18:02:25 2020 +0100

svga, winsys/svga: Fix persistent memory discard maps

The kernel driver requires immediate notification using a
BindGBSurface command when a graphics coherent memory resource changes
backing MOB, so that it can start dirty-tracking the new MOB.
Since we always use graphics coherent memory for persistent memory, enqueue
and flush a BindGBSurface commmand at map time rather than at unmap time.
Since we're dealing with persistent memory, It's OK to flush while mapped.

This fixes an issue with gnome-shell / Wayland which uses persistent
memory together with discard maps when we advertise ARB_buffer_storage.
XWayland clients will render incorrectly.

Fixes: 71b43490dd ("svga: Support ARB_buffer_storage")
Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Neha Bhende <bhenden at vmware.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
Reviewed-by: Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4399>
(cherry picked from commit 46fdc288fb52345134fd9aacd6d7ff71c7b747bb)

---

 .pick_status.json                                |  2 +-
 src/gallium/drivers/svga/svga_resource_buffer.h  | 18 +++++++++++++++++-
 src/gallium/drivers/svga/svga_resource_texture.c | 18 +++++++++++++++---
 src/gallium/drivers/svga/svga_winsys.h           |  7 ++++++-
 src/gallium/winsys/svga/drm/vmw_surface.c        | 10 +++++++++-
 src/gallium/winsys/svga/drm/vmw_surface.h        |  5 +++--
 6 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index e8d093daf1e..f48b048960e 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -148,7 +148,7 @@
         "description": "svga, winsys/svga: Fix persistent memory discard maps",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": "71b43490dd04c03d4027230b0939b81ab91650ca"
     },
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h
index 35ed35d61dd..b3559446fa9 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -285,7 +285,23 @@ svga_buffer_hw_storage_map(struct svga_context *svga,
    svga->hud.num_buffers_mapped++;
 
    if (sws->have_gb_objects) {
-      return svga->swc->surface_map(svga->swc, sbuf->handle, flags, retry);
+      struct svga_winsys_context *swc = svga->swc;
+      boolean rebind;
+      void *map;
+
+      map = swc->surface_map(swc, sbuf->handle, flags, retry, &rebind);
+      if (map && rebind) {
+         enum pipe_error ret;
+
+         ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
+         if (ret != PIPE_OK) {
+            svga_context_flush(svga, NULL);
+            ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
+            assert(ret == PIPE_OK);
+         }
+         svga_context_flush(svga, NULL);
+      }
+      return map;
    } else {
       *retry = FALSE;
       return sws->buffer_map(sws, sbuf->hwbuf, flags);
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index 4cc58e001c0..58b2f64d0b7 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -458,10 +458,11 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
    {
       SVGA3dSize baseLevelSize;
       uint8_t *map;
-      boolean retry;
+      boolean retry, rebind;
       unsigned offset, mip_width, mip_height;
+      struct svga_winsys_context *swc = svga->swc;
 
-      map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
+      map = swc->surface_map(swc, surf, usage, &retry, &rebind);
       if (map == NULL && retry) {
          /*
           * At this point, the svga_surfaces_flush() should already have
@@ -469,7 +470,18 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
           */
          svga->hud.surface_write_flushes++;
          svga_context_flush(svga, NULL);
-         map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
+         map = swc->surface_map(swc, surf, usage, &retry, &rebind);
+      }
+      if (map && rebind) {
+         enum pipe_error ret;
+
+         ret = SVGA3D_BindGBSurface(swc, surf);
+         if (ret != PIPE_OK) {
+            svga_context_flush(svga, NULL);
+            ret = SVGA3D_BindGBSurface(swc, surf);
+            assert(ret == PIPE_OK);
+         }
+         svga_context_flush(svga, NULL);
       }
 
       /*
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index 30d3f8776d9..20096c036c9 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -390,7 +390,11 @@ struct svga_winsys_context
 
    /**
     * Map a guest-backed surface.
+    * \param swc The winsys context
+    * \param surface The surface to map
     * \param flags  bitmaks of PIPE_TRANSFER_x flags
+    * \param retry Whether to flush and retry the map
+    * \param rebind Whether to issue an immediate rebind and flush.
     *
     * The surface_map() member is allowed to fail due to a
     * shortage of command buffer space, if the
@@ -401,7 +405,8 @@ struct svga_winsys_context
    void *
    (*surface_map)(struct svga_winsys_context *swc,
                   struct svga_winsys_surface *surface,
-                  unsigned flags, boolean *retry);
+                  unsigned flags, boolean *retry,
+                  boolean *rebind);
 
    /**
     * Unmap a guest-backed surface.
diff --git a/src/gallium/winsys/svga/drm/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c
index 6aa09e11b76..698cd11a28e 100644
--- a/src/gallium/winsys/svga/drm/vmw_surface.c
+++ b/src/gallium/winsys/svga/drm/vmw_surface.c
@@ -38,7 +38,8 @@
 void *
 vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
                             struct svga_winsys_surface *srf,
-                            unsigned flags, boolean *retry)
+                            unsigned flags, boolean *retry,
+                            boolean *rebind)
 {
    struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
    void *data = NULL;
@@ -47,6 +48,7 @@ vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
    struct vmw_winsys_screen *vws = vsrf->screen;
 
    *retry = FALSE;
+   *rebind = FALSE;
    assert((flags & (PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE)) != 0);
    mtx_lock(&vsrf->mutex);
 
@@ -121,6 +123,12 @@ vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
             if (vsrf->buf)
                vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf);
             vsrf->buf = vbuf;
+
+            /* Rebind persistent maps immediately */
+            if (flags & PIPE_TRANSFER_PERSISTENT) {
+               *rebind = TRUE;
+               vsrf->rebind = FALSE;
+            }
             goto out_mapped;
          } else
             vmw_svga_winsys_buffer_destroy(&vws->base, vbuf);
diff --git a/src/gallium/winsys/svga/drm/vmw_surface.h b/src/gallium/winsys/svga/drm/vmw_surface.h
index b1a1ce746b3..ab75fed5f97 100644
--- a/src/gallium/winsys/svga/drm/vmw_surface.h
+++ b/src/gallium/winsys/svga/drm/vmw_surface.h
@@ -88,8 +88,9 @@ vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
                                   struct vmw_svga_winsys_surface *src);
 void *
 vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
-			    struct svga_winsys_surface *srf,
-			    unsigned flags, boolean *retry);
+                            struct svga_winsys_surface *srf,
+                            unsigned flags, boolean *retry,
+                            boolean *rebind);
 void
 vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc,
                               struct svga_winsys_surface *srf,



More information about the mesa-commit mailing list