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

Author: Mike Blumenkrantz <[email protected]>
Date:   Mon Oct 24 11:58:13 2022 -0400

zink: allow direct memory mapping for any COHERENT+CACHED buffer

some drivers may provide this in heaps that get used by non-staging resources,
so avoid extra copies in that case

unlike the previous attempt at this optimization, this utilizes the screen-based
context for thread-safe transfers, which should avoid races/crashes

fix #8171

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21452>

---

 src/gallium/drivers/zink/zink_bo.h       |  1 +
 src/gallium/drivers/zink/zink_resource.c | 18 +++++++++++++++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_bo.h 
b/src/gallium/drivers/zink/zink_bo.h
index 42e5ec22563..42b1fc6437e 100644
--- a/src/gallium/drivers/zink/zink_bo.h
+++ b/src/gallium/drivers/zink/zink_bo.h
@@ -30,6 +30,7 @@
 #include "zink_batch.h"
 
 #define VK_VIS_VRAM (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | 
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
+#define VK_STAGING_RAM (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | 
VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
 #define VK_LAZY_VRAM (VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT | 
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
 
 
diff --git a/src/gallium/drivers/zink/zink_resource.c 
b/src/gallium/drivers/zink/zink_resource.c
index 95dd34eaa1e..60a81319034 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -1898,15 +1898,22 @@ zink_buffer_map(struct pipe_context *pctx,
          goto success;
       usage |= PIPE_MAP_UNSYNCHRONIZED;
    } else if (!(usage & PIPE_MAP_UNSYNCHRONIZED) &&
-              (((usage & PIPE_MAP_READ) && !(usage & PIPE_MAP_PERSISTENT) && 
res->base.b.usage != PIPE_USAGE_STAGING) || !res->obj->host_visible)) {
-      assert(!(usage & (TC_TRANSFER_MAP_THREADED_UNSYNC | 
PIPE_MAP_THREAD_SAFE)));
-      if (!res->obj->host_visible || !(usage & PIPE_MAP_ONCE)) {
+              (((usage & PIPE_MAP_READ) && !(usage & PIPE_MAP_PERSISTENT) &&
+               ((res->obj->bo->base.placement & VK_STAGING_RAM) != 
VK_STAGING_RAM)) ||
+              !res->obj->host_visible)) {
+      assert(!(usage & (TC_TRANSFER_MAP_THREADED_UNSYNC)));
+      if (!res->obj->host_visible || res->base.b.flags & 
PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY) {
 overwrite:
          trans->offset = box->x % 
screen->info.props.limits.minMemoryMapAlignment;
          trans->staging_res = pipe_buffer_create(&screen->base, 
PIPE_BIND_LINEAR, PIPE_USAGE_STAGING, box->width + trans->offset);
          if (!trans->staging_res)
             goto fail;
          struct zink_resource *staging_res = zink_resource(trans->staging_res);
+         if (usage & PIPE_MAP_THREAD_SAFE) {
+            /* this map can't access the passed context: use the copy context 
*/
+            zink_screen_lock_context(screen);
+            ctx = screen->copy_context;
+         }
          zink_copy_buffer(ctx, staging_res, res, trans->offset, box->x, 
box->width);
          res = staging_res;
          usage &= ~PIPE_MAP_UNSYNCHRONIZED;
@@ -1975,10 +1982,15 @@ overwrite:
       res->obj->persistent_maps++;
 
 success:
+   /* ensure the copy context gets unlocked */
+   if (ctx == screen->copy_context)
+      zink_screen_unlock_context(screen);
    *transfer = &trans->base.b;
    return ptr;
 
 fail:
+   if (ctx == screen->copy_context)
+      zink_screen_unlock_context(screen);
    destroy_transfer(ctx, trans);
    return NULL;
 }

Reply via email to