-
Notifications
You must be signed in to change notification settings - Fork 34
Add exception handling for vk::SystemError #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
f87c2d3
58e0fe7
f474f04
fb7a5c2
e37bb22
284e1ec
914f3cb
040f4a5
eede873
6cf1473
6bc04dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -243,6 +243,7 @@ class HelloTriangleApplication { | |
glfwInit(); | ||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); | ||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); | ||
|
||
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan Cross-Platform", nullptr, nullptr); | ||
glfwSetWindowUserPointer(window, this); | ||
glfwSetFramebufferSizeCallback(window, framebufferResizeCallback); | ||
|
@@ -1177,7 +1178,7 @@ class HelloTriangleApplication { | |
// Create synchronization objects | ||
void createSyncObjects() { | ||
imageAvailableSemaphores.reserve(MAX_FRAMES_IN_FLIGHT); | ||
renderFinishedSemaphores.reserve(MAX_FRAMES_IN_FLIGHT); | ||
renderFinishedSemaphores.reserve(swapChainImages.size()); | ||
inFlightFences.reserve(MAX_FRAMES_IN_FLIGHT); | ||
|
||
vk::SemaphoreCreateInfo semaphoreInfo{}; | ||
|
@@ -1187,22 +1188,21 @@ class HelloTriangleApplication { | |
|
||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { | ||
imageAvailableSemaphores.push_back(device.createSemaphore(semaphoreInfo)); | ||
renderFinishedSemaphores.push_back(device.createSemaphore(semaphoreInfo)); | ||
inFlightFences.push_back(device.createFence(fenceInfo)); | ||
} | ||
|
||
for (size_t i = 0; i < swapChainImages.size(); i++) { | ||
renderFinishedSemaphores.push_back(device.createSemaphore(semaphoreInfo)); | ||
} | ||
} | ||
|
||
// Clean up swap chain | ||
void cleanupSwapChain() { | ||
for (auto& framebuffer : swapChainFramebuffers) { | ||
framebuffer = nullptr; | ||
} | ||
swapChainFramebuffers.clear(); | ||
swapChainImageViews.clear(); | ||
|
||
for (auto& imageView : swapChainImageViews) { | ||
imageView = nullptr; | ||
} | ||
|
||
swapChain = nullptr; | ||
// Semaphores tied to swapchain image indices need to be rebuilt on resize | ||
renderFinishedSemaphores.clear(); | ||
} | ||
|
||
// Record command buffer | ||
|
@@ -1281,47 +1281,69 @@ class HelloTriangleApplication { | |
.commandBufferCount = 1, | ||
.pCommandBuffers = &*commandBuffers[currentFrame], | ||
.signalSemaphoreCount = 1, | ||
.pSignalSemaphores = &*renderFinishedSemaphores[currentFrame] | ||
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex] | ||
}; | ||
queue.submit(submitInfo, *inFlightFences[currentFrame]); | ||
|
||
const vk::PresentInfoKHR presentInfoKHR{ | ||
.waitSemaphoreCount = 1, | ||
.pWaitSemaphores = &*renderFinishedSemaphores[currentFrame], | ||
.swapchainCount = 1, | ||
.pSwapchains = &*swapChain, | ||
.pImageIndices = &imageIndex | ||
}; | ||
|
||
vk::Result result; | ||
try { | ||
result = queue.presentKHR(presentInfoKHR); | ||
} catch (vk::OutOfDateKHRError&) { | ||
result = vk::Result::eErrorOutOfDateKHR; | ||
} | ||
const vk::PresentInfoKHR presentInfoKHR{ | ||
.waitSemaphoreCount = 1, | ||
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex], | ||
.swapchainCount = 1, | ||
.pSwapchains = &*swapChain, | ||
.pImageIndices = &imageIndex | ||
}; | ||
|
||
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) { | ||
framebufferResized = false; | ||
recreateSwapChain(); | ||
} else if (result != vk::Result::eSuccess) { | ||
throw std::runtime_error("Failed to present swap chain image"); | ||
vk::Result result = queue.presentKHR(presentInfoKHR); | ||
|
||
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) { | ||
framebufferResized = false; | ||
recreateSwapChain(); | ||
} else if (result != vk::Result::eSuccess) { | ||
throw std::runtime_error("Failed to present swap chain image"); | ||
} | ||
} catch (const vk::SystemError& e) { | ||
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) { | ||
recreateSwapChain(); | ||
return; | ||
} else { | ||
throw; | ||
} | ||
} | ||
|
||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; | ||
} | ||
|
||
// Recreate swap chain | ||
void recreateSwapChain() { | ||
#if !PLATFORM_ANDROID | ||
// On desktop, wait until the framebuffer has a non-zero size (e.g., when window is minimized) | ||
int width = 0, height = 0; | ||
if (window) { | ||
glfwGetFramebufferSize(window, &width, &height); | ||
while (width == 0 || height == 0) { | ||
glfwGetFramebufferSize(window, &width, &height); | ||
glfwWaitEvents(); | ||
} | ||
} | ||
#endif | ||
// Wait for device to finish operations | ||
device.waitIdle(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note per recent spec updates, waiting for idle on the queue used for presentation is sufficient. Also, it would be best if VK_EXT_swapchain_maintenance1's present fence were used here instead. Is there a tutorial yet for smooth resize? I.e., using oldSwapchain to create the new swapchain and deferring cleanup until pending swaps have reached a point where it's safe to delete the old sawpchain(s)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, we should open 3 issues you presented here: The first two will require making changes to the tutorial itself as we don't want to just change the code without making sure the tutorial explains what needs to be done to be correct. The last will require a full tutorial which takes more time and planning; however, it should be done as we do see the request from time to time to give a sample on smooth resizing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We also need to take into account that VK_EXT_swapchain_maintenance1 isn't universally supported, and the KHR variant even less so. So would prob. need to be optional for now. |
||
|
||
// Clean up old swap chain | ||
cleanupSwapChain(); | ||
|
||
// Create new swap chain | ||
// Create new swap chain and dependent resources | ||
createSwapChain(); | ||
createImageViews(); | ||
createFramebuffers(); | ||
|
||
// Recreate per-swapchain-image present semaphores for presenting | ||
renderFinishedSemaphores.reserve(swapChainImages.size()); | ||
vk::SemaphoreCreateInfo semaphoreInfo{}; | ||
for (size_t i = 0; i < swapChainImages.size(); ++i) { | ||
renderFinishedSemaphores.push_back(device.createSemaphore(semaphoreInfo)); | ||
} | ||
} | ||
|
||
// Get required extensions | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this example still have renderFinishedSemaphores, but also have these presentCompleteSemaphore array that seems to server the same purpose, but with a slightly misleading name (It seems to be used more as a "rendering complete/present-ready" indicator, rather than a "present complete" indicator, the latter of which I'm not sure is possible to measure using semaphores in current Vulkan, which is what lead me to look closely at this code).
The Android file below seems to still use renderFinishedSemaphores in the manner that fits its name for what appears to be the same steps renderFinishedSemaphores is used here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'opps' is the why :) I made a bug. Thanks for the report, I'll address it.