Vulkan:在 window 调整大小后重新创建交换链时出现图像错误
Vulkan: Image error when recreating the swapchain after a window resize
所以我正在尝试通过重新创建交换链及其图像视图等来处理 window 大小调整。这是我正在使用的方法:
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();
}
问题是 有时 我在调整大小时出现此错误:
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)
说问题出在VkPresentInfoKHR
结构中pImageIndices
中的元素,我写成:
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;
您需要将图像从开始时的未定义布局转换为可呈现的图像格式,具体取决于您对其进行的操作。例如,如果您将它用作着色器中的纹理,则它需要采用 SHADER_READ_ONLY_OPTIMAL
布局。
您可以通过多种方式执行此操作,其中之一是 image memory barrier that you can submit 临时队列。并且您绝对需要在重新创建交换链后执行此操作,因为 window 调整大小操作会使您的整个上下文无效。
所以我正在尝试通过重新创建交换链及其图像视图等来处理 window 大小调整。这是我正在使用的方法:
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();
}
问题是 有时 我在调整大小时出现此错误:
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)
说问题出在VkPresentInfoKHR
结构中pImageIndices
中的元素,我写成:
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;
您需要将图像从开始时的未定义布局转换为可呈现的图像格式,具体取决于您对其进行的操作。例如,如果您将它用作着色器中的纹理,则它需要采用 SHADER_READ_ONLY_OPTIMAL
布局。
您可以通过多种方式执行此操作,其中之一是 image memory barrier that you can submit 临时队列。并且您绝对需要在重新创建交换链后执行此操作,因为 window 调整大小操作会使您的整个上下文无效。