简体   繁体   中英

Vulkan: Image error when recreating the swapchain after a window resize

So I'm trying to handle window resizing by recreating the swapchain and its image views and all that. This is the method that I'm using:

void VxRenderer::recreateSwapchain() {
    device.waitIdle();

    for (uint32_t i = 0; i < swapchainImageCount; ++i) {
        vkDestroyFramebuffer(device, framebuffers[i], nullptr);
        vkDestroyImageView(device, swapchainImageViews[i], nullptr);
    }

    vkResetCommandPool(device, commandPool, 0);
    vkDestroyPipeline(device, pipeline, nullptr);
    vkDestroySwapchainKHR(device, swapchain, nullptr);

    createSwapchain();
    getSwapchainImages();
    createSwapchainImageViews();
    createFramebuffers();
    createGraphicsPipeline();
    recordCommandBuffers();
}

The problem is that sometimes I get this error when resizing:

Validation Error: [ VUID-VkPresentInfoKHR-pImageIndices-01296 ] Object 0: handle = 0x1d7260c6cc8,
type = VK_OBJECT_TYPE_QUEUE; | MessageID = 0xc7aabc16 | vkQueuePresentKHR(): pSwapchains[0] images
passed to present must be in layout VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR
but is in VK_IMAGE_LAYOUT_UNDEFINED. The Vulkan spec states: Each element of pImageIndices must be the
index of a presentable image acquired from the swapchain specified by the corresponding element of the
pSwapchains array, and the presented image subresource must be in the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
layout at the time the operation is executed on a VkDevice
(https://github.com/KhronosGroup/Vulkan-Docs/search?q=)VUID-VkPresentInfoKHR-pImageIndices-01296)

It says that the problem comes from the elements in pImageIndices in the VkPresentInfoKHR structure, which I wrote as:

uint32_t imageIndex;
VkResult result =
        vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, imageAcquiredSemaphores[currentImage], VK_NULL_HANDLE, &imageIndex);

if (result == VK_ERROR_OUT_OF_DATE_KHR) {
    recreateSwapchain();
    return;
}

...

VkPresentInfoKHR presentInfo;
presentInfo.sType              = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.pNext              = nullptr;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores    = &renderFinishedSemaphores[currentImage];
presentInfo.swapchainCount     = 1;
presentInfo.pSwapchains        = &swapchain;
presentInfo.pImageIndices      = &imageIndex;
presentInfo.pResults           = nullptr;

You need to transfer your image from the undefined layout in which it starts to a presentable image format, depending on what exactly you're doing with it. For example, if you're using it as a texture in a shader, it needs to be in SHADER_READ_ONLY_OPTIMAL layout.

You can do this in multiple ways, one of them being an image memory barrier that you can submit to a transient queue. And you absolutely need to do this after recreating your swap chain, because your entire context is invalidated by the window resize operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM