Check swapchain acquire result and rebuild if necessary, error handling (refs #320)

This commit is contained in:
saschawillems 2017-04-15 10:27:12 +02:00
parent 2d3f1dba09
commit 1912101fe8
2 changed files with 23 additions and 24 deletions

View file

@ -120,7 +120,7 @@ public:
#endif #endif
) )
{ {
VkResult err; VkResult err = VK_SUCCESS;
// Create the os-specific surface // Create the os-specific surface
#ifdef _WIN32 #ifdef _WIN32
@ -156,6 +156,10 @@ public:
#endif #endif
#endif #endif
if (err != VK_SUCCESS) {
vks::tools::exitFatal("Could not create surface!", "Fatal error");
}
// Get available queue family properties // Get available queue family properties
uint32_t queueCount; uint32_t queueCount;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL); vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL);
@ -224,13 +228,11 @@ public:
// Get list of supported surface formats // Get list of supported surface formats
uint32_t formatCount; uint32_t formatCount;
err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, NULL); VK_CHECK_RESULT(fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, NULL));
assert(!err);
assert(formatCount > 0); assert(formatCount > 0);
std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount); std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, surfaceFormats.data()); VK_CHECK_RESULT(fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, surfaceFormats.data()));
assert(!err);
// If the surface format list only includes one entry with VK_FORMAT_UNDEFINED, // If the surface format list only includes one entry with VK_FORMAT_UNDEFINED,
// there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM
@ -299,24 +301,19 @@ public:
*/ */
void create(uint32_t *width, uint32_t *height, bool vsync = false) void create(uint32_t *width, uint32_t *height, bool vsync = false)
{ {
VkResult err;
VkSwapchainKHR oldSwapchain = swapChain; VkSwapchainKHR oldSwapchain = swapChain;
// Get physical device surface properties and formats // Get physical device surface properties and formats
VkSurfaceCapabilitiesKHR surfCaps; VkSurfaceCapabilitiesKHR surfCaps;
err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps); VK_CHECK_RESULT(fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps));
assert(!err);
// Get available present modes // Get available present modes
uint32_t presentModeCount; uint32_t presentModeCount;
err = fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL); VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL));
assert(!err);
assert(presentModeCount > 0); assert(presentModeCount > 0);
std::vector<VkPresentModeKHR> presentModes(presentModeCount); std::vector<VkPresentModeKHR> presentModes(presentModeCount);
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data()));
err = fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
assert(!err);
VkExtent2D swapchainExtent = {}; VkExtent2D swapchainExtent = {};
// If width (and height) equals the special value 0xFFFFFFFF, the size of the surface will be set by the swapchain // If width (and height) equals the special value 0xFFFFFFFF, the size of the surface will be set by the swapchain
@ -422,8 +419,7 @@ public:
swapchainCI.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; swapchainCI.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
} }
err = fpCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapChain); VK_CHECK_RESULT(fpCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapChain));
assert(!err);
// If an existing swap chain is re-created, destroy the old swap chain // If an existing swap chain is re-created, destroy the old swap chain
// This also cleans up all the presentable images // This also cleans up all the presentable images
@ -435,14 +431,11 @@ public:
} }
fpDestroySwapchainKHR(device, oldSwapchain, nullptr); fpDestroySwapchainKHR(device, oldSwapchain, nullptr);
} }
VK_CHECK_RESULT(fpGetSwapchainImagesKHR(device, swapChain, &imageCount, NULL));
err = fpGetSwapchainImagesKHR(device, swapChain, &imageCount, NULL);
assert(!err);
// Get the swap chain images // Get the swap chain images
images.resize(imageCount); images.resize(imageCount);
err = fpGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data()); VK_CHECK_RESULT(fpGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data()));
assert(!err);
// Get the swap chain buffers containing the image and imageview // Get the swap chain buffers containing the image and imageview
buffers.resize(imageCount); buffers.resize(imageCount);
@ -470,8 +463,7 @@ public:
colorAttachmentView.image = buffers[i].image; colorAttachmentView.image = buffers[i].image;
err = vkCreateImageView(device, &colorAttachmentView, nullptr, &buffers[i].view); VK_CHECK_RESULT(vkCreateImageView(device, &colorAttachmentView, nullptr, &buffers[i].view));
assert(!err);
} }
} }

View file

@ -552,8 +552,15 @@ void VulkanExampleBase::getOverlayText(VulkanTextOverlay *textOverlay)
void VulkanExampleBase::prepareFrame() void VulkanExampleBase::prepareFrame()
{ {
// Acquire the next image from the swap chaing // Acquire the next image from the swap chain
VK_CHECK_RESULT(swapChain.acquireNextImage(semaphores.presentComplete, &currentBuffer)); VkResult err = swapChain.acquireNextImage(semaphores.presentComplete, &currentBuffer);
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE) or no longer optimal for presentation (SUBOPTIMAL)
if ((err == VK_ERROR_OUT_OF_DATE_KHR) || (err == VK_SUBOPTIMAL_KHR)) {
windowResize();
}
else {
VK_CHECK_RESULT(err);
}
} }
void VulkanExampleBase::submitFrame() void VulkanExampleBase::submitFrame()