diff options
-rwxr-xr-x | main.c | 30 |
1 files changed, 19 insertions, 11 deletions
@@ -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; } |