From 1bd6e659ae359992041baf04f714f28715607abd Mon Sep 17 00:00:00 2001 From: Kyle Pelham Date: Sun, 15 Sep 2024 02:41:39 +0100 Subject: [PATCH] fix god awful clean up --- src/renderer.cpp | 42 +++++++++++++++++++++++++++++---- src/window.cpp | 61 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 16 deletions(-) diff --git a/src/renderer.cpp b/src/renderer.cpp index 747c582..27e5715 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -29,16 +29,48 @@ Renderer::~Renderer() void Renderer::shutdown() { - vkDestroyDescriptorPool(device, descriptorPool, allocator); + // Wait for the device to finish all operations + if (device != VK_NULL_HANDLE) + vkDeviceWaitIdle(device); + + // Destroy the descriptor pool + if (descriptorPool != VK_NULL_HANDLE) { + vkDestroyDescriptorPool(device, descriptorPool, allocator); + descriptorPool = VK_NULL_HANDLE; + } + + // Destroy the pipeline cache + if (pipelineCache != VK_NULL_HANDLE) { + vkDestroyPipelineCache(device, pipelineCache, allocator); + pipelineCache = VK_NULL_HANDLE; + } + + // Destroy the logical device + if (device != VK_NULL_HANDLE) { + vkDestroyDevice(device, allocator); + device = VK_NULL_HANDLE; + } #ifdef VULKAN_DEBUG_REPORT // Remove the debug report callback - auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); - vkDestroyDebugReportCallbackEXT(instance, debugReport, allocator); + if (debugReport != VK_NULL_HANDLE) { + auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); + vkDestroyDebugReportCallbackEXT(instance, debugReport, allocator); + debugReport = VK_NULL_HANDLE; + } #endif - vkDestroyDevice(device, allocator); - vkDestroyInstance(instance, allocator); + // Destroy the Vulkan instance + if (instance != VK_NULL_HANDLE) + { + vkDestroyInstance(instance, allocator); + instance = VK_NULL_HANDLE; + } + + // Reset other members + physicalDevice = VK_NULL_HANDLE; + queueFamilyIndex = UINT32_MAX; + queue = VK_NULL_HANDLE; } void Renderer::createInstance() diff --git a/src/window.cpp b/src/window.cpp index 4526d09..30f4ae2 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -164,37 +164,72 @@ Window::Window(WindowSettings settings) : Window::~Window() { - // Shutdown ImGui + // Wait for the device to finish all operations + auto renderer = Application::Get().getRenderer(); + vkDeviceWaitIdle(renderer->getDevice()); + + // Clean up ImGui if (imguiContext) { // Set current context ImGuiContext* backupContext = ImGui::GetCurrentContext(); ImGui::SetCurrentContext(imguiContext); imguiContext = nullptr; - // Wait for the device to be idle - auto renderer = Application::Get().getRenderer(); - vkDeviceWaitIdle(renderer->getDevice()); - - // Shutdown context + // Shutdown everything within the context ImGui_ImplVulkan_Shutdown(); ImGui_ImplGlfw_Shutdown(); + + // Destroy the window context (before full context destruction) + ImGui_ImplVulkanH_DestroyWindow( + renderer->getInstance(), + renderer->getDevice(), + imguiWindow, + renderer->getAllocator() + ); + + // Destroy the context ImGui::DestroyContext(); // Restore the previous context if it exists if (backupContext) ImGui::SetCurrentContext(backupContext); } - // Destroy the glfw window + // Remove the custom window procedures (just in case, don't want null pointers) + #ifdef _WIN32 + if (settings.useCustomTitlebar) { + HWND hWnd = glfwGetWin32Window(windowHandle); + if (wndProcMap.find(hWnd) != wndProcMap.end()) { + SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast(wndProcMap[hWnd])); + wndProcMap.erase(hWnd); + } + } + #endif + + // Clean up GLFW resources if (windowHandle) { glfwDestroyWindow(windowHandle); windowHandle = nullptr; } - // Destroy the imgui window context - if (imguiWindow) { - delete imguiWindow; - imguiWindow = nullptr; + // Clean up allocated command buffers + for (auto& cmdBuf : allocatedCommandBuffers) { + if (!cmdBuf.empty()) + vkFreeCommandBuffers( + renderer->getDevice(), + imguiWindow->Frames[0].CommandPool, + (uint32_t)cmdBuf.size(), + cmdBuf.data() + ); + } + + // Clear the resource free queue + for (auto& queue : resourceFreeQueue) { + for (auto& func : queue) + func(); + queue.clear(); } + + delete imguiWindow; } void Window::render() @@ -540,6 +575,10 @@ void Window::setupForCustomTitlebar() { #ifdef _WIN32 HWND hWnd = glfwGetWin32Window(windowHandle); + if (hWnd == nullptr) { + fmt::print("Failed to get the window handle for custom titlebar setup.\n"); + return; + } LONG_PTR lStyle = GetWindowLongPtr(hWnd, GWL_STYLE); lStyle |= WS_THICKFRAME;