EQMG / Acid

A high speed C++17 Vulkan game engine
https://equilibrium.games
MIT License
1.75k stars 153 forks source link

Resizing Window Crashes #83

Open engineer1109 opened 5 years ago

engineer1109 commented 5 years ago

SwapChain should be recreated while resizing windows. Destroy the swapchain and create the swapchain again. For example:

VkResult res = swapChain.queuePresent(queue, currentBuffer, semaphores.renderComplete);
    if (!((res == VK_SUCCESS) || (res == VK_SUBOPTIMAL_KHR))) {
        if (res == VK_ERROR_OUT_OF_DATE_KHR) {
            // Swap chain is no longer compatible with the surface and needs to be recreated
            windowResize();
            return;
        } else {
            VK_CHECK_RESULT(res);
        }
    }
    VK_CHECK_RESULT(vkQueueWaitIdle(queue));
void VulkanBase::windowResize()
{
    if (!prepared)
    {
        return;
    }
    prepared = false;

    // Ensure all operations on the device have been finished before destroying resources
    vkDeviceWaitIdle(device);

    // Recreate swap chain
    width = destWidth;
    height = destHeight;
    setupSwapChain();

    // Recreate the frame buffers
    vkDestroyImageView(device, depthStencil.view, nullptr);
    vkDestroyImage(device, depthStencil.image, nullptr);
    vkFreeMemory(device, depthStencil.mem, nullptr);
    setupDepthStencil();    
    for (uint32_t i = 0; i < frameBuffers.size(); i++) {
        vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
    }
    setupFrameBuffer();

    if ((width > 0.0f) && (height > 0.0f)) {
        if (settings.overlay) {
            UIOverlay.resize(width, height);
        }
    }

    // Command buffers need to be recreated as they may store
    // references to the recreated frame buffer
    destroyCommandBuffers();
    createCommandBuffers();
    buildCommandBuffers();

    vkDeviceWaitIdle(device);

    if ((width > 0.0f) && (height > 0.0f)) {
        camera.updateAspectRatio((float)width / (float)height);
    }

    // Notify derived class
    windowResized();
    viewChanged();

    prepared = true;
}
engineer1109 commented 5 years ago

@mattparks I am writing a project for vulkan: https://github.com/engineer1109/LearnVulkan The project contains the above codes. I hope this will help you. You can see the swapchain recreation while resizing window to deal with the VK_ERROR_OUT_OF_DATE_KHR. awesomeface awesomeface2

engineer1109 commented 4 years ago

I found your code is crashed on this while resizing :

Graphics.cpp: 354 vkCmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

GDB stack info 1 ?? 0x7fffe198c69b 2 ?? 0x7fffe19cf33b 3 ?? 0x7fffe19cf4ac 4 ?? 0x7fffe193a91c 5 DispatchCmdBeginRenderPass(VkCommandBuffer_T , VkRenderPassBeginInfo const , VkSubpassContents) 0x7fffcb3e95d5 6 vulkan_layer_chassis::CmdBeginRenderPass(VkCommandBuffer_T , VkRenderPassBeginInfo const , VkSubpassContents) 0x7fffcb35008d 7 acid::Graphics::StartRenderpass Graphics.cpp 354 0x7ffff7685ab7 8 acid::Graphics::Update Graphics.cpp 65 0x7ffff7683b77 9 acid::Engine::UpdateStage Engine.cpp 124 0x7ffff760a53b 10 acid::Engine::Run Engine.cpp 111 0x7ffff760a44e 11 main MainApp.cpp 20 0x5555555ac9da