From 4bee678df3afb654c4f52987fefd039750609976 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 9 Jun 2022 09:20:01 -0400 Subject: [PATCH] zink: defer old swapchain destruction ensure that swapchains that are about to be presented asynchronously cannot be destroyed Fixes: 8ade5588e39 ("zink: add kopper api") Reviewed-by: Adam Jackson Part-of: --- src/gallium/drivers/zink/zink_kopper.c | 24 +++++++++++++++++++++--- src/gallium/drivers/zink/zink_kopper.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c index cfce107f1be..a0302b66456 100644 --- a/src/gallium/drivers/zink/zink_kopper.c +++ b/src/gallium/drivers/zink/zink_kopper.c @@ -143,6 +143,21 @@ destroy_swapchain(struct zink_screen *screen, struct kopper_swapchain *cswap) free(cswap); } +static void +prune_old_swapchains(struct zink_screen *screen, struct kopper_displaytarget *cdt, bool wait) +{ + while (cdt->old_swapchain) { + struct kopper_swapchain *cswap = cdt->old_swapchain; + if (cswap->async_presents) { + if (wait) + continue; + return; + } + cdt->old_swapchain = cswap->next; + destroy_swapchain(screen, cswap); + } +} + static struct hash_entry * find_dt_entry(struct zink_screen *screen, const struct kopper_displaytarget *cdt) { @@ -182,7 +197,7 @@ zink_kopper_deinit_displaytarget(struct zink_screen *screen, struct kopper_displ _mesa_hash_table_remove(&screen->dts, he); simple_mtx_unlock(&screen->dt_lock); destroy_swapchain(screen, cdt->swapchain); - destroy_swapchain(screen, cdt->old_swapchain); + prune_old_swapchains(screen, cdt, true); VKSCR(DestroySurfaceKHR)(screen->instance, cdt->surface, NULL); cdt->swapchain = cdt->old_swapchain = NULL; cdt->surface = VK_NULL_HANDLE; @@ -309,8 +324,11 @@ update_swapchain(struct zink_screen *screen, struct kopper_displaytarget *cdt, u struct kopper_swapchain *cswap = kopper_CreateSwapchain(screen, cdt, w, h, &error); if (!cswap) return error; - destroy_swapchain(screen, cdt->old_swapchain); - cdt->old_swapchain = cdt->swapchain; + prune_old_swapchains(screen, cdt, false); + struct kopper_swapchain **pswap = &cdt->old_swapchain; + while (*pswap) + *pswap = (*pswap)->next; + *pswap = cdt->swapchain; cdt->swapchain = cswap; return kopper_GetSwapchainImages(screen, cdt->swapchain); diff --git a/src/gallium/drivers/zink/zink_kopper.h b/src/gallium/drivers/zink/zink_kopper.h index 836dac0c9a0..7e3e9d81beb 100644 --- a/src/gallium/drivers/zink/zink_kopper.h +++ b/src/gallium/drivers/zink/zink_kopper.h @@ -30,6 +30,7 @@ #include "kopper_interface.h" struct kopper_swapchain { + struct kopper_swapchain *next; VkSwapchainKHR swapchain; VkImage *images; bool *inits;