Module: Mesa
Branch: staging/23.0
Commit: 9fdfa9d9bbca09697efa0bc1e40ed13a978f716a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=9fdfa9d9bbca09697efa0bc1e40ed13a978f716a

Author: Charmaine Lee <[email protected]>
Date:   Tue Feb 14 03:47:39 2023 +0200

svga: use upload buffer if texture has pending changes

When establishing a texture transfer map, if there is any pending changes on the
texture, instead of trying direct map with DONTBLOCK first, just
use the upload buffer path.

Fixes piglit tests gen-teximages, arb_copy_images-formats

Cc: mesa-stable

Reviewed-by: Neha Bhende <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21393>
(cherry picked from commit 1b9b060f0eee19da426daffe37de30a9200b15b2)

---

 .pick_status.json                                |  2 +-
 src/gallium/drivers/svga/svga_resource_texture.c | 11 ++++++-----
 src/gallium/drivers/svga/svga_resource_texture.h | 19 ++++++++++++++++---
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 62b52a9702f..c58741cde52 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -256,7 +256,7 @@
         "description": "svga: use upload buffer if texture has pending 
changes",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c 
b/src/gallium/drivers/svga/svga_resource_texture.c
index 38f32ce3b84..3a5c744540e 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2023 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -357,7 +357,7 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
    else {
       assert(usage & PIPE_MAP_WRITE);
       if ((usage & PIPE_MAP_UNSYNCHRONIZED) == 0) {
-         if (svga_is_texture_dirty(tex, st->slice, level)) {
+         if (svga_is_texture_level_dirty(tex, st->slice, level)) {
             /*
              * do a surface flush if the subresource has been modified
              * in this command buffer.
@@ -567,14 +567,15 @@ svga_texture_transfer_map(struct pipe_context *pipe,
                                !(st->base.usage & PIPE_MAP_READ);
       boolean was_rendered_to =
          svga_was_texture_rendered_to(svga_texture(texture));
+      boolean is_dirty = svga_is_texture_dirty(svga_texture(texture));
 
-      /* If the texture was already rendered to and upload buffer
-       * is supported, then we will use upload buffer to
+      /* If the texture was already rendered to or has pending changes and
+       * upload buffer is supported, then we will use upload buffer to
        * avoid the need to read back the texture content; otherwise,
        * we'll first try to map directly to the GB surface, if it is blocked,
        * then we'll try the upload buffer.
        */
-      if (was_rendered_to && can_use_upload) {
+      if ((was_rendered_to || is_dirty) && can_use_upload) {
          map = svga_texture_transfer_map_upload(svga, st);
       }
       else {
diff --git a/src/gallium/drivers/svga/svga_resource_texture.h 
b/src/gallium/drivers/svga/svga_resource_texture.h
index e1872faad61..32b42dd0ee7 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.h
+++ b/src/gallium/drivers/svga/svga_resource_texture.h
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2023 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -85,6 +85,11 @@ struct svga_texture
     */
    boolean can_use_upload;
 
+   /**
+    * Whether texture is modified.  Set if any of the dirty bits is set.
+    */
+   boolean modified;
+
    unsigned size;  /**< Approximate size in bytes */
 
    /** array indexed by cube face or 3D/array slice, one bit per mipmap level 
*/
@@ -242,6 +247,7 @@ svga_set_texture_dirty(struct svga_texture *tex,
 {
    check_face_level(tex, face, level);
    tex->dirty[face] |= 1 << level;
+   tex->modified = TRUE;
 }
 
 static inline void
@@ -251,16 +257,23 @@ svga_clear_texture_dirty(struct svga_texture *tex)
    for (i = 0; i < tex->b.depth0 * tex->b.array_size; i++) {
       tex->dirty[i] = 0;
    }
+   tex->modified = FALSE;
 }
 
 static inline boolean
-svga_is_texture_dirty(const struct svga_texture *tex,
-                      unsigned face, unsigned level)
+svga_is_texture_level_dirty(const struct svga_texture *tex,
+                            unsigned face, unsigned level)
 {
    check_face_level(tex, face, level);
    return !!(tex->dirty[face] & (1 << level));
 }
 
+static inline boolean
+svga_is_texture_dirty(const struct svga_texture *tex)
+{
+   return tex->modified;
+}
+
 struct pipe_resource *
 svga_texture_create(struct pipe_screen *screen,
                     const struct pipe_resource *template);

Reply via email to