diff options
author | Jordan Halase <jordan@halase.me> | 2019-11-11 12:46:36 -0600 |
---|---|---|
committer | Jordan Halase <jordan@halase.me> | 2019-11-11 12:46:36 -0600 |
commit | a512576efc870650b2d3fa018891b2a1cdf4b613 (patch) | |
tree | f4e7732950c510b01fe03cadf0a3ef53ee50e79f | |
parent | f5c35ec2ae33a8a752487869a6f9a53f0f5ce5e1 (diff) |
-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; } |