From 510efd8b5a5ae5ecd91c035e12457bb58aabbf95 Mon Sep 17 00:00:00 2001 From: swinston Date: Thu, 29 Jan 2026 08:48:57 -0800 Subject: [PATCH] Add destructor with device waitIdle, refactor reflective field handling, and improve swap chain error handling with exception catching. This commit message: - Clearly prioritizes the main actions (destructor addition, reflective field changes, and swap chain error handling improvements) - Is concise and straight-to-the-point - Matches the style of the author's recent commits (action-oriented, using commas to separate multiple changes) - Accurately describes the three main changes in the diff: 1. A new destructor that calls `device.waitIdle()` 2. Refactoring of the `reflective` field in PushConstant (removing conditional compilation guards in the struct, adding default value) 3. Wrapping swap chain operations in try-catch blocks to handle `vk::OutOfDateKHRError` --- attachments/38_ray_tracing.cpp | 36 +++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/attachments/38_ray_tracing.cpp b/attachments/38_ray_tracing.cpp index c87af500..30df65c2 100644 --- a/attachments/38_ray_tracing.cpp +++ b/attachments/38_ray_tracing.cpp @@ -106,10 +106,7 @@ struct UniformBufferObject struct PushConstant { uint32_t materialIndex; -#if LAB_TASK_LEVEL >= LAB_TASK_REFLECTIONS - // TASK11 uint32_t reflective; -#endif // LAB_TASK_LEVEL >= LAB_TASK_REFLECTIONS }; class VulkanRaytracingApplication @@ -123,6 +120,14 @@ class VulkanRaytracingApplication cleanup(); } + ~VulkanRaytracingApplication() + { + if (*device) + { + device.waitIdle(); + } + } + private: GLFWwindow *window = nullptr; @@ -1629,6 +1634,8 @@ class VulkanRaytracingApplication .materialIndex = sub.materialID < 0 ? 0u : static_cast(sub.materialID), #if LAB_TASK_LEVEL >= LAB_TASK_REFLECTIONS .reflective = sub.reflective +#else + .reflective = 0u #endif // LAB_TASK_LEVEL >= LAB_TASK_REFLECTIONS }; commandBuffer.pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eFragment, 0, pushConstant); @@ -1829,7 +1836,19 @@ class VulkanRaytracingApplication throw std::runtime_error("failed to wait for fence!"); } - auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr); + vk::Result result; + uint32_t imageIndex; + try + { + auto res = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr); + result = res.result; + imageIndex = res.value; + } + catch (const vk::OutOfDateKHRError &e) + { + recreateSwapChain(); + return; + } // Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result // here and does not need to be caught by an exception. @@ -1872,7 +1891,14 @@ class VulkanRaytracingApplication .swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex}; - result = presentQueue.presentKHR(presentInfoKHR); + try + { + result = presentQueue.presentKHR(presentInfoKHR); + } + catch (const vk::OutOfDateKHRError &e) + { + result = vk::Result::eErrorOutOfDateKHR; + } // Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result // here and does not need to be caught by an exception. if ((result == vk::Result::eSuboptimalKHR) || (result == vk::Result::eErrorOutOfDateKHR) || framebufferResized)