Mesa (master): svga: Fix out-of-sync backing surface

Brian Paul brianp at kemper.freedesktop.org
Fri Apr 7 19:51:09 UTC 2017


Module: Mesa
Branch: master
Commit: ab96d1baf40d67b4ea9e685e4f5ea5c90f77d269
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ab96d1baf40d67b4ea9e685e4f5ea5c90f77d269

Author: Charmaine Lee <charmainel at vmware.com>
Date:   Tue Apr  4 13:02:45 2017 -0600

svga: Fix out-of-sync backing surface

When a backing surface is reused, it is possible that
the original surface has been changed. So before the backing surface
is bound again, we need to sync up the surface.
This patch creates a new helper function svga_texture_copy_handle_resource()
to sync up the backing surface resource.

This patch, together with the backing surface dirty bit fix, fixes
the rendering corruption in NobelClinicianViewer when rotating the model.

Also tested with MTT glretrace, piglit, Cinebench, Turbine.

Reviewed-by: Brian Paul <brianp at vmware.com>

---

 src/gallium/drivers/svga/svga_surface.c | 91 +++++++++++++++++++++++++--------
 1 file changed, 70 insertions(+), 21 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
index 846acccace..18bce3467f 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -103,6 +103,43 @@ svga_texture_copy_handle(struct svga_context *svga,
 }
 
 
+/* A helper function to sync up the two surface handles.
+ */
+static void
+svga_texture_copy_handle_resource(struct svga_context *svga,
+                                  struct svga_texture *src_tex,
+                                  struct svga_winsys_surface *dst,
+                                  unsigned int numMipLevels,
+                                  unsigned int numLayers,
+                                  unsigned int zoffset,
+                                  unsigned int mipoffset,
+                                  unsigned int layeroffset)
+{
+   unsigned int i, j;
+
+   for (i = 0; i < numMipLevels; i++) {
+      unsigned int miplevel = i + mipoffset;
+
+      for (j = 0; j < numLayers; j++) {
+         if (svga_is_texture_level_defined(src_tex, j+layeroffset, miplevel)) {
+            unsigned depth = (zoffset < 0 ?
+                              u_minify(src_tex->b.b.depth0, miplevel) : 1);
+
+            svga_texture_copy_handle(svga,
+                                     src_tex->handle,
+                                     0, 0, zoffset,
+                                     miplevel,
+                                     j + layeroffset,
+                                     dst, 0, 0, 0, i, j,
+                                     u_minify(src_tex->b.b.width0, miplevel),
+                                     u_minify(src_tex->b.b.height0, miplevel),
+                                     depth);
+         }
+      }
+   }
+}
+
+
 struct svga_winsys_surface *
 svga_texture_view_surface(struct svga_context *svga,
                           struct svga_texture *tex,
@@ -118,7 +155,6 @@ svga_texture_view_surface(struct svga_context *svga,
 {
    struct svga_screen *ss = svga_screen(svga->pipe.screen);
    struct svga_winsys_surface *handle;
-   uint32_t i, j;
    unsigned z_offset = 0;
    boolean validated;
 
@@ -172,25 +208,10 @@ svga_texture_view_surface(struct svga_context *svga,
    if (zslice_pick >= 0)
       z_offset = zslice_pick;
 
-   for (i = 0; i < key->numMipLevels; i++) {
-      for (j = 0; j < key->numFaces * key->arraySize; j++) {
-         if (svga_is_texture_level_defined(tex, j + layer_pick, i + start_mip)) {
-            unsigned depth = (zslice_pick < 0 ?
-                              u_minify(tex->b.b.depth0, i + start_mip) :
-                              1);
-
-            svga_texture_copy_handle(svga,
-                                     tex->handle,
-                                     0, 0, z_offset,
-                                     i + start_mip,
-                                     j + layer_pick,
-                                     handle, 0, 0, 0, i, j,
-                                     u_minify(tex->b.b.width0, i + start_mip),
-                                     u_minify(tex->b.b.height0, i + start_mip),
-                                     depth);
-         }
-      }
-   }
+   svga_texture_copy_handle_resource(svga, tex, handle,
+                                     key->numMipLevels,
+                                     key->numFaces * key->arraySize,
+                                     z_offset, start_mip, layer_pick);
 
    return handle;
 }
@@ -374,11 +395,12 @@ svga_create_surface(struct pipe_context *pipe,
 static struct svga_surface *
 create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
 {
+   struct svga_texture *tex = svga_texture(s->base.texture);
+
    SVGA_STATS_TIME_PUSH(svga_sws(svga),
                         SVGA_STATS_TIME_CREATEBACKEDSURFACEVIEW);
 
    if (!s->backed) {
-      struct svga_texture *tex = svga_texture(s->base.texture);
       struct pipe_surface *backed_view;
 
       backed_view = svga_create_surface_view(&svga->pipe,
@@ -390,6 +412,33 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
 
       s->backed = svga_surface(backed_view);
    }
+   else {
+      /*
+       * There is already an existing backing surface, but we still need to
+       * sync the handles.
+       */
+      struct svga_surface *bs = s->backed;
+      unsigned int layer, zslice;
+
+      assert(bs->handle);
+
+      switch (tex->b.b.target) {
+      case PIPE_TEXTURE_CUBE:
+      case PIPE_TEXTURE_1D_ARRAY:
+      case PIPE_TEXTURE_2D_ARRAY:
+         layer = s->base.u.tex.first_layer;
+         zslice = 0;
+         break;
+      default:
+         layer = 0;
+         zslice = s->base.u.tex.first_layer;
+      }
+
+      svga_texture_copy_handle_resource(svga, tex, bs->handle,
+                                        bs->key.numMipLevels,
+                                        bs->key.numFaces * bs->key.arraySize,
+                                        zslice, s->base.u.tex.level, layer);
+   }
 
    svga_mark_surface_dirty(&s->backed->base);
 




More information about the mesa-commit mailing list