Skip to content

[fix] Window resize crash#13

Merged
yooian merged 12 commits into
mainfrom
fix/resize-crash
Apr 16, 2026
Merged

[fix] Window resize crash#13
yooian merged 12 commits into
mainfrom
fix/resize-crash

Conversation

@yooian

@yooian yooian commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Fix ImGui Assertion Crash on Window Resize

Background & Motivation

Currently, the Loom application crashes with an ImGui assertion failure when the window is resized. The crash occurs because the main loop unconditionally starts an ImGui frame (imgui.beginFrame()), but the Vulkan backend (vulkan.drawFrame()) may abort the render process midway if it detects a window resize or an out-of-date swapchain. This early exit skips the corresponding imgui.endFrame() call, leaving the ImGui state machine unbalanced and triggering an assertion on the next frame.

Proposed Solution

The industry-standard, professional solution is to split the monolithic VulkanContext::drawFrame into two distinct phases: beginFrame() and endFrame().
By attempting to acquire a Vulkan frame before building the UI, the application can gracefully skip generating UI data if the swapchain needs to be recreated. This prevents wasted CPU cycles and ensures the ImGui lifecycle remains perfectly balanced. Exposing the VkCommandBuffer to the main loop also sets a robust architectural foundation for future compute shader dispatches.

Key Files & Context

  • include/gpu/VulkanContext.hpp
  • src/gpu/VulkanContext.cpp
  • src/main.cpp

Implementation Steps

  1. Refactor VulkanContext.hpp
  • Replace the existing drawFrame declaration with a split lifecycle:
// Remove:                                                                                                                     
// void drawFrame(loom::ui::ImGuiRenderer& imgui);                                                                                                                                                                                               
// Add:                                                                                                                        
VkCommandBuffer beginFrame();                                                                                                  
void endFrame(VkCommandBuffer cmd, loom::ui::ImGuiRenderer& imgui);               
  1. Implement VulkanContext::beginFrame() in VulkanContext.cpp
  • Extract the first half of the old drawFrame logic:
  • Check loomWindow->wasResized(). If true, call recreateSwapchain(), reset the flag, and return VK_NULL_HANDLE.
  • Wait for the in-flight fence.
  • Acquire the next swapchain image via vkAcquireNextImageKHR. If it returns VK_ERROR_OUT_OF_DATE_KHR, recreate the swapchain and return VK_NULL_HANDLE.
  • Reset the fence and begin the command buffer for the current frame.
  • Return the active VkCommandBuffer.
  1. Implement VulkanContext::endFrame() in VulkanContext.cpp
    Extract the second half of the old drawFrame logic:
  • Transition the swapchain image to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
  • Begin dynamic rendering (vkCmdBeginRendering).
  • Call imgui.endFrame(cmd) to record UI draw data.
  • End dynamic rendering (vkCmdEndRendering).
  • Transition the swapchain image to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.
  • End the command buffer, submit to the graphics queue, and present the image.
  • Advance m_currentFrame.
  1. Update the Main Loop in main.cpp
  • Restructure the main loop to conditionally build the UI based on the success of vulkan.beginFrame():
while (!window.shouldClose()) {                                                                                               
    window.pollEvents();                                                                                                      
                                                                                                                              
    if (VkCommandBuffer cmd = vulkan.beginFrame()) {                                                                         
        // Build UI                                                                                                           
        imgui.beginFrame();                                                                                                   
        imgui.drawDockspace();                                                                                                
        nodeEditor.draw("Node Editor");                                                                                       
                                                                                                                              
        // Evaluate Graph...                                                                                                  
                                                                                                                               
        // Render and Present                                                                                                 
        vulkan.endFrame(cmd, imgui);                                                                                          
    }                                                                                                                         
                                                                                                                              
    imagePool.flushPendingReleases();                                                                                         
}                                                                                                                             
                                                                                                                    
## Verification & Testing                                                                                                            
1. Build: Ensure the project compiles successfully without errors.                                                               
2. Run & Resize: Launch the application and rapidly resize the window multiple times, both horizontally and vertically.
3. Validate: Confirm that the ImGui assertion crash is entirely resolved and the application remains stable during continuous resize events.

@yooian yooian self-assigned this Apr 16, 2026
@yooian yooian marked this pull request as ready for review April 16, 2026 00:57
@yooian yooian merged commit 392a57f into main Apr 16, 2026
5 checks passed
@yooian yooian deleted the fix/resize-crash branch April 16, 2026 00:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant