vulkan: populate oldSwapchain field during swap chain creation. Also fix crash if window is already closed, when quitting.

Fixes #2174
This commit is contained in:
Sasha Szpakowski
2025-04-07 20:56:22 -03:00
parent de5495bb03
commit ae2e68f414
2 changed files with 41 additions and 9 deletions
+40 -8
View File
@@ -815,8 +815,13 @@ void Graphics::unSetMode()
created = false;
cleanupSwapChain();
vkDestroySurfaceKHR(instance, surface, nullptr);
cleanupSwapChain(true);
if (surface != VK_NULL_HANDLE)
{
vkDestroySurfaceKHR(instance, surface, nullptr);
surface = VK_NULL_HANDLE;
}
}
void Graphics::setActive(bool enable)
@@ -2021,18 +2026,34 @@ void Graphics::createSwapChain()
createInfo.compositeAlpha = chooseCompositeAlpha(swapChainSupport.capabilities);
createInfo.presentMode = presentMode;
createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = VK_NULL_HANDLE;
createInfo.oldSwapchain = swapChain;
VkSwapchainKHR newSwapChain = VK_NULL_HANDLE;
VkResult result = vkCreateSwapchainKHR(device, &createInfo, nullptr, &newSwapChain);
VkResult result = vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain);
if (result != VK_SUCCESS)
throw love::Exception("Failed to create Vulkan swap chain: %s", Vulkan::getErrorString(result));
if (swapChain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR(device, swapChain, nullptr);
swapChain = VK_NULL_HANDLE;
}
swapChain = newSwapChain;
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
swapChainImages.resize(imageCount);
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
}
else
{
if (swapChain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR(device, swapChain, nullptr);
swapChain = VK_NULL_HANDLE;
}
// Use a fake backbuffer. Creation is deferred until startRecordingGraphicsCommands
// because newTexture needs an active command buffer to do its initial
// layout transitions.
@@ -3424,19 +3445,27 @@ void Graphics::cleanup()
}
}
void Graphics::cleanupSwapChain()
void Graphics::cleanupSwapChain(bool destroySwapChainObject)
{
if (colorImage)
{
cleanupFramebuffers(colorImageView, swapChainPixelFormat);
vkDestroyImageView(device, colorImageView, nullptr);
colorImageView = VK_NULL_HANDLE;
vmaDestroyImage(vmaAllocator, colorImage, colorImageAllocation);
colorImage = VK_NULL_HANDLE;
}
if (depthImage)
{
cleanupFramebuffers(depthImageView, depthStencilPixelFormat);
vkDestroyImageView(device, depthImageView, nullptr);
depthImageView = VK_NULL_HANDLE;
vmaDestroyImage(vmaAllocator, depthImage, depthImageAllocation);
depthImage = VK_NULL_HANDLE;
}
for (const auto &swapChainImageView : swapChainImageViews)
{
@@ -3444,18 +3473,21 @@ void Graphics::cleanupSwapChain()
vkDestroyImageView(device, swapChainImageView, nullptr);
}
swapChainImageViews.clear();
vkDestroySwapchainKHR(device, swapChain, nullptr);
swapChainImages.clear();
fakeBackbuffer.set(nullptr);
swapChain = VK_NULL_HANDLE;
if (destroySwapChainObject && swapChain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR(device, swapChain, nullptr);
swapChain = VK_NULL_HANDLE;
}
}
void Graphics::recreateSwapChain()
{
vkDeviceWaitIdle(device);
cleanupSwapChain();
cleanupSwapChain(false);
createSwapChain();
createImageViews();
+1 -1
View File
@@ -337,7 +337,7 @@ private:
void createCommandBuffers();
void createSyncObjects();
void cleanup();
void cleanupSwapChain();
void cleanupSwapChain(bool destroySwapChainObject);
void recreateSwapChain();
void initDynamicState();
void beginSwapChainFrame();