From a512576efc870650b2d3fa018891b2a1cdf4b613 Mon Sep 17 00:00:00 2001 From: Jordan Halase Date: Mon, 11 Nov 2019 12:46:36 -0600 Subject: Automatically collect swapchain garbage --- main.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index 3903579..2e38bf2 100755 --- a/main.c +++ b/main.c @@ -1600,24 +1600,32 @@ static bool canDestroySwapchain(const struct RenderVulkan *vk, return !notReady; } -/* FIXME: Race condition! Swapchains cannot be destroyed until they are done - * being rendered to. +/** Collects old swapchains only, leaving the latest one intact. This will + * only delete the swapchains not in use. */ void rvkCollectSwapchainGarbage(struct RenderVulkan *vk) { - struct SwapchainVulkan *old, *pp = vk->swapchain; - uint32_t count = 0; - if (pp && (pp)->old) { - for(pp = (pp)->old; pp; pp = old) { - old = (pp)->old; - rvkDestroySwapchain(vk, pp); + struct SwapchainVulkan *old, *sc, *lag = vk->swapchain; + uint32_t count = 0, del = 0; + if (lag && lag->old) { + for(sc = lag->old; sc; sc = old) { + old = sc->old; + if (canDestroySwapchain(vk, sc)) { + rvkDestroySwapchain(vk, sc); + lag->old = old; + ++del; + } else { + lag = lag->old; + } ++count; } - vk->swapchain->old = NULL; } - printf("Collected %d retired swapchains\n", count); + if (count > 1) { + printf("Collected %d/%d retired swapchains\n", del, count); + } } +/** This must not be called until all swapchains are no longer in use. */ void rvkDestroyAllSwapchains(struct RenderVulkan *vk) { struct SwapchainVulkan *swapchain, *old; @@ -1821,6 +1829,7 @@ PuglStatus onDisplay(PuglView *view) vk->dev->vkQueuePresentKHR(vk->graphicsQueue, &presentInfo); + rvkCollectSwapchainGarbage(vk); if (args.continuous) ++framesDrawn; return PUGL_SUCCESS; } @@ -1864,7 +1873,6 @@ PuglStatus onEvent(PuglView *view, const PuglEvent *e) break; case 'c': // Manually collect swapchain garbage - vk->dev->vkDeviceWaitIdle(vk->device); rvkCollectSwapchainGarbage(vk); break; } -- cgit v1.2.1