summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2022-06-10 13:24:20 -0400
committerDylan Baker <dylan.c.baker@intel.com>2022-06-15 16:12:59 -0700
commit4108785f13b4ebae7f1bb8037db2ed54c641223c (patch)
tree2bef49faa0bd4a5240965d243a34b930ce974136
parentd0d37c1f9e1da80c15b403f9f16a338036d3d153 (diff)
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@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17009> (cherry picked from commit ea9e30f9d27593d7fdcc95e6559951127110b8d4)
-rw-r--r--.pick_status.json2
-rw-r--r--src/gallium/drivers/zink/zink_kopper.c32
-rw-r--r--src/gallium/drivers/zink/zink_screen.c18
-rw-r--r--src/gallium/drivers/zink/zink_screen.h2
4 files changed, 52 insertions, 2 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 5f86a7b780f..bce0eebf448 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;
};