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

Author: Mike Blumenkrantz <[email protected]>
Date:   Tue Feb 21 10:11:15 2023 -0500

zink: add locking for zink_screen::copy_context and defer creation

the copy context isn't always used, so this allows its creation to
be deferred and potentially save a bunch of memory

also add locking for multi-context thread safety

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

---

 src/gallium/drivers/zink/zink_query.c    |  3 +++
 src/gallium/drivers/zink/zink_resource.c |  6 +++++-
 src/gallium/drivers/zink/zink_screen.c   | 26 ++++++++++++++++++++------
 src/gallium/drivers/zink/zink_screen.h   |  5 +++++
 src/gallium/drivers/zink/zink_types.h    |  1 +
 5 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_query.c 
b/src/gallium/drivers/zink/zink_query.c
index 37f1dbdac3d..155354aced0 100644
--- a/src/gallium/drivers/zink/zink_query.c
+++ b/src/gallium/drivers/zink/zink_query.c
@@ -4,6 +4,7 @@
 #include "zink_clear.h"
 #include "zink_program.h"
 #include "zink_resource.h"
+#include "zink_screen.h"
 
 #include "util/u_dump.h"
 #include "util/u_inlines.h"
@@ -1322,6 +1323,7 @@ zink_get_timestamp(struct pipe_screen *pscreen)
          mesa_loge("ZINK: vkGetCalibratedTimestampsEXT failed (%s)", 
vk_Result_to_str(result));
       }
    } else {
+      zink_screen_lock_context(screen);
       struct pipe_context *pctx = &screen->copy_context->base;
       struct pipe_query *pquery = pctx->create_query(pctx, 
PIPE_QUERY_TIMESTAMP, 0);
       if (!pquery)
@@ -1331,6 +1333,7 @@ zink_get_timestamp(struct pipe_screen *pscreen)
       pctx->end_query(pctx, pquery);
       pctx->get_query_result(pctx, pquery, true, &result);
       pctx->destroy_query(pctx, pquery);
+      zink_screen_unlock_context(screen);
       timestamp = result.u64;
    }
    timestamp_to_nanoseconds(screen, &timestamp);
diff --git a/src/gallium/drivers/zink/zink_resource.c 
b/src/gallium/drivers/zink/zink_resource.c
index 41f3b50d87d..95dd34eaa1e 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -1486,10 +1486,14 @@ zink_resource_get_handle(struct pipe_screen *pscreen,
             unsigned bind = ZINK_BIND_DMABUF;
             if (!(res->base.b.bind & PIPE_BIND_SHARED))
                bind |= PIPE_BIND_SHARED;
-            if (!add_resource_bind(screen->copy_context, res, bind))
+            zink_screen_lock_context(screen);
+            if (!add_resource_bind(screen->copy_context, res, bind)) {
+               zink_screen_unlock_context(screen);
                return false;
+            }
             p_atomic_inc(&screen->image_rebind_counter);
             screen->copy_context->base.flush(&screen->copy_context->base, 
NULL, 0);
+            zink_screen_unlock_context(screen);
             obj = res->obj;
          }
 
diff --git a/src/gallium/drivers/zink/zink_screen.c 
b/src/gallium/drivers/zink/zink_screen.c
index c23f3ca6518..40f4fad23fb 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -1415,6 +1415,7 @@ zink_destroy_screen(struct pipe_screen *pscreen)
       zink_kopper_deinit_displaytarget(screen, entry->data);
    simple_mtx_destroy(&screen->dt_lock);
 
+   simple_mtx_destroy(&screen->copy_context_lock);
    if (screen->copy_context)
       screen->copy_context->base.destroy(&screen->copy_context->base);
 
@@ -2577,6 +2578,24 @@ zink_create_semaphore(struct zink_screen *screen)
    return ret == VK_SUCCESS ? sem : VK_NULL_HANDLE;
 }
 
+void
+zink_screen_lock_context(struct zink_screen *screen)
+{
+   simple_mtx_lock(&screen->copy_context_lock);
+   if (!screen->copy_context)
+      screen->copy_context = 
zink_context(screen->base.context_create(&screen->base, NULL, 
ZINK_CONTEXT_COPY_ONLY));
+   if (!screen->copy_context) {
+      mesa_loge("zink: failed to create copy context");
+      /* realistically there's nothing that can be done here */
+   }
+}
+
+void
+zink_screen_unlock_context(struct zink_screen *screen)
+{
+   simple_mtx_unlock(&screen->copy_context_lock);
+}
+
 static bool
 init_layouts(struct zink_screen *screen)
 {
@@ -2997,12 +3016,7 @@ zink_internal_create_screen(const struct 
pipe_screen_config *config)
    if (!zink_descriptor_layouts_init(screen))
       goto fail;
 
-
-   screen->copy_context = 
zink_context(screen->base.context_create(&screen->base, NULL, 
ZINK_CONTEXT_COPY_ONLY));
-   if (!screen->copy_context) {
-      mesa_loge("zink: failed to create copy context");
-      goto fail;
-   }
+   simple_mtx_init(&screen->copy_context_lock, mtx_plain);
 
    screen->optimal_keys = !screen->need_decompose_attrs &&
                           screen->info.have_EXT_non_seamless_cube_map &&
diff --git a/src/gallium/drivers/zink/zink_screen.h 
b/src/gallium/drivers/zink/zink_screen.h
index d65f50ac88d..b6b30b9ec57 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -102,6 +102,11 @@ zink_screen_handle_vkresult(struct zink_screen *screen, 
VkResult ret)
 VkSemaphore
 zink_create_semaphore(struct zink_screen *screen);
 
+void
+zink_screen_lock_context(struct zink_screen *screen);
+void
+zink_screen_unlock_context(struct zink_screen *screen);
+
 VkFormat
 zink_get_format(struct zink_screen *screen, enum pipe_format format);
 
diff --git a/src/gallium/drivers/zink/zink_types.h 
b/src/gallium/drivers/zink/zink_types.h
index de2629878bb..78be78360ab 100644
--- a/src/gallium/drivers/zink/zink_types.h
+++ b/src/gallium/drivers/zink/zink_types.h
@@ -1276,6 +1276,7 @@ struct zink_screen {
    VkSemaphore sem;
    VkFence fence;
    struct util_queue flush_queue;
+   simple_mtx_t copy_context_lock;
    struct zink_context *copy_context;
 
    simple_mtx_t semaphores_lock;

Reply via email to