Mesa (staging/22.1): zink: add implicit sync workaround for non-mesa drivers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 15 16:22:55 UTC 2022


Module: Mesa
Branch: staging/22.1
Commit: 5eb42642746653769fbf8ce90ee5c5d2eacaeeb8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5eb42642746653769fbf8ce90ee5c5d2eacaeeb8

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri Jun 10 13:24:20 2022 -0400

zink: add implicit sync workaround for non-mesa drivers

implicit sync is hard, and many drivers get it wrong, so assume that
anyone who isn't mesa might need some hand-holding

cc: mesa-stable

Reviewed-by: Adam Jackson <ajax at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17009>
(cherry picked from commit ea9e30f9d27593d7fdcc95e6559951127110b8d4)

---

 .pick_status.json                      |  2 +-
 src/gallium/drivers/zink/zink_kopper.c | 32 +++++++++++++++++++++++++++++++-
 src/gallium/drivers/zink/zink_screen.c | 18 ++++++++++++++++++
 src/gallium/drivers/zink/zink_screen.h |  2 ++
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index ea720d71462..aa5e1a0e5a5 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -1750,7 +1750,7 @@
         "description": "zink: add implicit sync workaround for non-mesa drivers",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c
index a0302b66456..5b3622248e9 100644
--- a/src/gallium/drivers/zink/zink_kopper.c
+++ b/src/gallium/drivers/zink/zink_kopper.c
@@ -606,10 +606,39 @@ kopper_present(void *data, void *gdata, int thread_idx)
    struct kopper_displaytarget *cdt = cpi->res->obj->dt;
    struct kopper_swapchain *swapchain = cpi->swapchain;
    struct zink_screen *screen = gdata;
-   VkResult error;
+   VkResult error = VK_SUCCESS;
    cpi->info.pResults = &error;
 
    simple_mtx_lock(&screen->queue_lock);
+   if (screen->driver_workarounds.implicit_sync && cdt->type != KOPPER_WIN32) {
+      if (!screen->fence) {
+         VkFenceCreateInfo fci = {0};
+         fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+         VKSCR(CreateFence)(screen->dev, &fci, NULL, &screen->fence);
+      }
+      VKSCR(ResetFences)(screen->dev, 1, &screen->fence);
+      VkSubmitInfo si = {0};
+      si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+      si.waitSemaphoreCount = 1;
+      si.pWaitSemaphores = cpi->info.pWaitSemaphores;
+      VkPipelineStageFlags stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+      si.pWaitDstStageMask = &stages;
+
+      error = VKSCR(QueueSubmit)(screen->queue, 1, &si, screen->fence);
+      if (!zink_screen_handle_vkresult(screen, error)) {
+         simple_mtx_unlock(&screen->queue_lock);
+         VKSCR(DestroySemaphore)(screen->dev, cpi->sem, NULL);
+         goto out;
+      }
+      error = VKSCR(WaitForFences)(screen->dev, 1, &screen->fence, VK_TRUE, UINT64_MAX);
+      if (!zink_screen_handle_vkresult(screen, error)) {
+         simple_mtx_unlock(&screen->queue_lock);
+         VKSCR(DestroySemaphore)(screen->dev, cpi->sem, NULL);
+         goto out;
+      }
+      cpi->info.pWaitSemaphores = NULL;
+      cpi->info.waitSemaphoreCount = 0;
+   }
    VkResult error2 = VKSCR(QueuePresentKHR)(screen->thread_queue, &cpi->info);
    simple_mtx_unlock(&screen->queue_lock);
    swapchain->last_present = cpi->image;
@@ -652,6 +681,7 @@ kopper_present(void *data, void *gdata, int thread_idx)
       _mesa_hash_table_insert(swapchain->presents, (void*)(uintptr_t)next, arr);
    }
    util_dynarray_append(arr, VkSemaphore, cpi->sem);
+out:
    if (thread_idx != -1)
       p_atomic_dec(&swapchain->async_presents);
    free(cpi);
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index cdfd7e76caa..06b9982ac2c 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -1246,6 +1246,9 @@ zink_destroy_screen(struct pipe_screen *pscreen)
    if (screen->prev_sem)
       VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
 
+   if (screen->fence)
+      VKSCR(DestroyFence)(screen->dev, screen->fence, NULL);
+
    if (screen->threaded)
       util_queue_destroy(&screen->flush_queue);
 
@@ -2114,6 +2117,21 @@ zink_get_sample_pixel_grid(struct pipe_screen *pscreen, unsigned sample_count,
 static void
 init_driver_workarounds(struct zink_screen *screen)
 {
+   /* enable implicit sync for all non-mesa drivers */
+   screen->driver_workarounds.implicit_sync = true;
+   switch (screen->info.driver_props.driverID) {
+   case VK_DRIVER_ID_MESA_RADV:
+   case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
+   case VK_DRIVER_ID_MESA_LLVMPIPE:
+   case VK_DRIVER_ID_MESA_TURNIP:
+   case VK_DRIVER_ID_MESA_V3DV:
+   case VK_DRIVER_ID_MESA_PANVK:
+   case VK_DRIVER_ID_MESA_VENUS:
+      screen->driver_workarounds.implicit_sync = false;
+      break;
+   default:
+      break;
+   }
    screen->driver_workarounds.color_write_missing = !screen->info.have_EXT_color_write_enable;
    screen->driver_workarounds.depth_clip_control_missing = !screen->info.have_EXT_depth_clip_control;
    if (screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA) {
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index 74f7966ca34..7ea4a63781c 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -86,6 +86,7 @@ struct zink_screen {
    uint32_t last_finished; //this is racy but ultimately doesn't matter
    VkSemaphore sem;
    VkSemaphore prev_sem;
+   VkFence fence;
    struct util_queue flush_queue;
    struct zink_context *copy_context;
 
@@ -184,6 +185,7 @@ struct zink_screen {
    struct {
       bool color_write_missing;
       bool depth_clip_control_missing;
+      bool implicit_sync;
    } driver_workarounds;
 };
 



More information about the mesa-commit mailing list