From ea9e30f9d27593d7fdcc95e6559951127110b8d4 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 10 Jun 2022 13:24:20 -0400 Subject: [PATCH] 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 Part-of: --- src/gallium/drivers/zink/zink_kopper.c | 32 +++++++++++++++++++++++++++++++- src/gallium/drivers/zink/zink_screen.c | 18 ++++++++++++++++++ src/gallium/drivers/zink/zink_screen.h | 2 ++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c index a0302b6..5b36222 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 5b99e1b..65dd99a 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -1262,6 +1262,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); @@ -2064,6 +2067,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_AMD_PROPRIETARY) diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index bbc98f0..b14aff9 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -103,6 +103,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; @@ -201,6 +202,7 @@ struct zink_screen { struct { bool color_write_missing; bool depth_clip_control_missing; + bool implicit_sync; } driver_workarounds; }; -- 2.7.4