Mesa (main): zink: implement PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY when resizable bar not present

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Aug 30 13:58:05 UTC 2021


Module: Mesa
Branch: main
Commit: 849033e6d8ba7befeb560278bb9b24c2469de498
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=849033e6d8ba7befeb560278bb9b24c2469de498

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri Jul 30 09:20:10 2021 -0400

zink: implement PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY when resizable bar not present

this helps in some cases to avoid allocating and mapping large staging resources

Acked-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12579>

---

 src/gallium/drivers/zink/zink_resource.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c
index 67fb4aae982..6b440b2f49a 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -710,6 +710,16 @@ resource_create(struct pipe_screen *pscreen,
    res->internal_format = templ->format;
    if (templ->target == PIPE_BUFFER) {
       util_range_init(&res->valid_buffer_range);
+      if (!screen->resizable_bar && templ->width0 >= 8196) {
+         /* We don't want to evict buffers from VRAM by mapping them for CPU access,
+          * because they might never be moved back again. If a buffer is large enough,
+          * upload data by copying from a temporary GTT buffer. 8K might not seem much,
+          * but there can be 100000 buffers.
+          *
+          * This tweak improves performance for viewperf.
+          */
+         res->base.b.flags |= PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY;
+      }
    } else {
       res->format = zink_get_format(screen, templ->format);
       res->layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -1100,6 +1110,18 @@ zink_buffer_map(struct pipe_context *pctx,
       usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
    }
 
+   /* If a buffer in VRAM is too large and the range is discarded, don't
+    * map it directly. This makes sure that the buffer stays in VRAM.
+    */
+   bool force_discard_range = false;
+   if (usage & (PIPE_MAP_DISCARD_WHOLE_RESOURCE | PIPE_MAP_DISCARD_RANGE) &&
+       !(usage & PIPE_MAP_PERSISTENT) &&
+       res->base.b.flags & PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY) {
+      usage &= ~(PIPE_MAP_DISCARD_WHOLE_RESOURCE | PIPE_MAP_UNSYNCHRONIZED);
+      usage |= PIPE_MAP_DISCARD_RANGE;
+      force_discard_range = true;
+   }
+
    if (usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE &&
        !(usage & (PIPE_MAP_UNSYNCHRONIZED | TC_TRANSFER_MAP_NO_INVALIDATE))) {
       assert(usage & PIPE_MAP_WRITE);
@@ -1120,7 +1142,7 @@ zink_buffer_map(struct pipe_context *pctx,
       /* Check if mapping this buffer would cause waiting for the GPU.
        */
 
-      if (!res->obj->host_visible ||
+      if (!res->obj->host_visible || force_discard_range ||
           !zink_resource_usage_check_completion(screen, res, ZINK_RESOURCE_ACCESS_RW)) {
          /* Do a wait-free write-only transfer using a temporary buffer. */
          unsigned offset;



More information about the mesa-commit mailing list