Skip to content

Commit b67e5c2

Browse files
Merge pull request #85 from gpx1000/address-resize-issue-73
Add exception handling for vk::SystemError
2 parents 19859be + 6bc04dc commit b67e5c2

21 files changed

+584
-274
lines changed

attachments/17_swap_chain_recreation.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class HelloTriangleApplication {
8282
glfwInit();
8383

8484
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
85+
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
8586

8687
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
8788
glfwSetWindowUserPointer(window, this);
@@ -520,14 +521,23 @@ class HelloTriangleApplication {
520521
queue.submit(submitInfo, *inFlightFences[currentFrame]);
521522

522523

523-
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
524-
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
525-
result = queue.presentKHR( presentInfoKHR );
526-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
527-
framebufferResized = false;
528-
recreateSwapChain();
529-
} else if (result != vk::Result::eSuccess) {
530-
throw std::runtime_error("failed to present swap chain image!");
524+
try {
525+
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
526+
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
527+
result = queue.presentKHR( presentInfoKHR );
528+
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
529+
framebufferResized = false;
530+
recreateSwapChain();
531+
} else if (result != vk::Result::eSuccess) {
532+
throw std::runtime_error("failed to present swap chain image!");
533+
}
534+
} catch (const vk::SystemError& e) {
535+
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
536+
recreateSwapChain();
537+
return;
538+
} else {
539+
throw;
540+
}
531541
}
532542
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
533543
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;

attachments/18_vertex_input.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class HelloTriangleApplication {
106106
glfwInit();
107107

108108
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
109+
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
109110

110111
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
111112
glfwSetWindowUserPointer(window, this);
@@ -261,8 +262,9 @@ class HelloTriangleApplication {
261262
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
262263
} );
263264

264-
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
265-
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
265+
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
266+
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
267+
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
266268
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
267269

268270
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
@@ -296,11 +298,12 @@ class HelloTriangleApplication {
296298
throw std::runtime_error("Could not find a queue for graphics and present -> terminating");
297299
}
298300

299-
// query for Vulkan 1.3 features
300-
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
301+
// query for required features (Vulkan 1.1 and 1.3)
302+
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
301303
{}, // vk::PhysicalDeviceFeatures2
302-
{.synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
303-
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
304+
{ .shaderDrawParameters = true }, // vk::PhysicalDeviceVulkan11Features
305+
{ .synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
306+
{ .extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
304307
};
305308

306309
// create a Device
@@ -537,14 +540,23 @@ class HelloTriangleApplication {
537540
queue.submit(submitInfo, *inFlightFences[currentFrame]);
538541

539542

540-
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
541-
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
542-
result = queue.presentKHR( presentInfoKHR );
543-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
544-
framebufferResized = false;
545-
recreateSwapChain();
546-
} else if (result != vk::Result::eSuccess) {
547-
throw std::runtime_error("failed to present swap chain image!");
543+
try {
544+
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
545+
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
546+
result = queue.presentKHR( presentInfoKHR );
547+
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
548+
framebufferResized = false;
549+
recreateSwapChain();
550+
} else if (result != vk::Result::eSuccess) {
551+
throw std::runtime_error("failed to present swap chain image!");
552+
}
553+
} catch (const vk::SystemError& e) {
554+
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
555+
recreateSwapChain();
556+
return;
557+
} else {
558+
throw;
559+
}
548560
}
549561
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
550562
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;

attachments/19_vertex_buffer.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class HelloTriangleApplication {
109109
glfwInit();
110110

111111
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
112+
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
112113

113114
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
114115
glfwSetWindowUserPointer(window, this);
@@ -265,8 +266,9 @@ class HelloTriangleApplication {
265266
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
266267
} );
267268

268-
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
269-
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
269+
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
270+
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
271+
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
270272
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
271273

272274
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
@@ -300,11 +302,12 @@ class HelloTriangleApplication {
300302
throw std::runtime_error("Could not find a queue for graphics and present -> terminating");
301303
}
302304

303-
// query for Vulkan 1.3 features
304-
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
305+
// query for required features (Vulkan 1.1 and 1.3)
306+
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
305307
{}, // vk::PhysicalDeviceFeatures2
306-
{.synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
307-
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
308+
{ .shaderDrawParameters = true }, // vk::PhysicalDeviceVulkan11Features
309+
{ .synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
310+
{ .extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
308311
};
309312

310313
// create a Device
@@ -569,14 +572,23 @@ class HelloTriangleApplication {
569572
queue.submit(submitInfo, *inFlightFences[currentFrame]);
570573

571574

572-
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
573-
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
574-
result = queue.presentKHR( presentInfoKHR );
575-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
576-
framebufferResized = false;
577-
recreateSwapChain();
578-
} else if (result != vk::Result::eSuccess) {
579-
throw std::runtime_error("failed to present swap chain image!");
575+
try {
576+
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
577+
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
578+
result = queue.presentKHR( presentInfoKHR );
579+
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
580+
framebufferResized = false;
581+
recreateSwapChain();
582+
} else if (result != vk::Result::eSuccess) {
583+
throw std::runtime_error("failed to present swap chain image!");
584+
}
585+
} catch (const vk::SystemError& e) {
586+
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
587+
recreateSwapChain();
588+
return;
589+
} else {
590+
throw;
591+
}
580592
}
581593
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
582594
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;

attachments/20_staging_buffer.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class HelloTriangleApplication {
109109
glfwInit();
110110

111111
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
112+
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
112113

113114
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
114115
glfwSetWindowUserPointer(window, this);
@@ -265,8 +266,9 @@ class HelloTriangleApplication {
265266
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
266267
} );
267268

268-
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
269-
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
269+
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
270+
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
271+
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
270272
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
271273

272274
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
@@ -300,11 +302,12 @@ class HelloTriangleApplication {
300302
throw std::runtime_error("Could not find a queue for graphics and present -> terminating");
301303
}
302304

303-
// query for Vulkan 1.3 features
304-
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
305+
// query for required features (Vulkan 1.1 and 1.3)
306+
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
305307
{}, // vk::PhysicalDeviceFeatures2
306-
{.synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
307-
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
308+
{ .shaderDrawParameters = true }, // vk::PhysicalDeviceVulkan11Features
309+
{ .synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
310+
{ .extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
308311
};
309312

310313
// create a Device
@@ -588,14 +591,23 @@ class HelloTriangleApplication {
588591
queue.submit(submitInfo, *inFlightFences[currentFrame]);
589592

590593

591-
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
592-
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
593-
result = queue.presentKHR( presentInfoKHR );
594-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
595-
framebufferResized = false;
596-
recreateSwapChain();
597-
} else if (result != vk::Result::eSuccess) {
598-
throw std::runtime_error("failed to present swap chain image!");
594+
try {
595+
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
596+
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
597+
result = queue.presentKHR( presentInfoKHR );
598+
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
599+
framebufferResized = false;
600+
recreateSwapChain();
601+
} else if (result != vk::Result::eSuccess) {
602+
throw std::runtime_error("failed to present swap chain image!");
603+
}
604+
} catch (const vk::SystemError& e) {
605+
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
606+
recreateSwapChain();
607+
return;
608+
} else {
609+
throw;
610+
}
599611
}
600612
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
601613
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;

0 commit comments

Comments
 (0)