From 09e1d25d097865c73ca64f87f7c5643ec16d251c Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 10 Dec 2023 07:13:42 -0500 Subject: [PATCH] Fix a crash in VulkanWindow when trying to close one --- parts/mdl/vulkanwindow.cpp | 32 ++++++++++++++++++++++---------- renderer/include/renderer.hpp | 2 ++ renderer/src/renderer.cpp | 8 ++++++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/parts/mdl/vulkanwindow.cpp b/parts/mdl/vulkanwindow.cpp index 7b0b577..3887f03 100644 --- a/parts/mdl/vulkanwindow.cpp +++ b/parts/mdl/vulkanwindow.cpp @@ -20,16 +20,19 @@ VulkanWindow::VulkanWindow(MDLPart *part, Renderer *renderer, QVulkanInstance *i void VulkanWindow::exposeEvent(QExposeEvent *) { - if (isExposed()) { - if (!m_initialized) { - m_initialized = true; + if (isExposed() && !m_initialized) { + m_initialized = true; - auto surface = m_instance->surfaceForWindow(this); - if (!m_renderer->initSwapchain(surface, width() * screen()->devicePixelRatio(), height() * screen()->devicePixelRatio())) - m_initialized = false; - else - render(); - } + auto surface = m_instance->surfaceForWindow(this); + if (!m_renderer->initSwapchain(surface, width() * screen()->devicePixelRatio(), height() * screen()->devicePixelRatio())) + m_initialized = false; + else + render(); + } + + if (!isExposed() && m_initialized) { + m_initialized = false; + m_renderer->destroySwapchain(); } } @@ -42,8 +45,17 @@ bool VulkanWindow::event(QEvent *e) case QEvent::Resize: { QResizeEvent *resizeEvent = (QResizeEvent *)e; auto surface = m_instance->surfaceForWindow(this); - m_renderer->resize(surface, resizeEvent->size().width() * screen()->devicePixelRatio(), resizeEvent->size().height() * screen()->devicePixelRatio()); + if (surface != nullptr) { + m_renderer->resize(surface, + resizeEvent->size().width() * screen()->devicePixelRatio(), + resizeEvent->size().height() * screen()->devicePixelRatio()); + } } break; + case QEvent::PlatformSurface: + if (static_cast(e)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed && m_initialized) { + m_renderer->destroySwapchain(); + } + break; case QEvent::MouseButtonPress: { auto mouseEvent = dynamic_cast(e); diff --git a/renderer/include/renderer.hpp b/renderer/include/renderer.hpp index edec2ed..1a7f0d2 100644 --- a/renderer/include/renderer.hpp +++ b/renderer/include/renderer.hpp @@ -68,6 +68,8 @@ public: bool initSwapchain(VkSurfaceKHR surface, int width, int height); void resize(VkSurfaceKHR surface, int width, int height); + void destroySwapchain(); + RenderModel addModel(const physis_MDL &model, int lod); void reloadModel(RenderModel &model, uint32_t lod); RenderTexture addTexture(uint32_t width, uint32_t height, const uint8_t *data, uint32_t data_size); diff --git a/renderer/src/renderer.cpp b/renderer/src/renderer.cpp index 4ed5672..83f73ba 100644 --- a/renderer/src/renderer.cpp +++ b/renderer/src/renderer.cpp @@ -426,6 +426,14 @@ void Renderer::resize(VkSurfaceKHR surface, int width, int height) initSwapchain(surface, width, height); } +void Renderer::destroySwapchain() +{ + if (swapchain != VK_NULL_HANDLE) { + vkDestroySwapchainKHR(device, swapchain, nullptr); + swapchain = VK_NULL_HANDLE; + } +} + void Renderer::render(std::vector models) { vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, std::numeric_limits::max());