summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2025-01-19 02:11:50 +0100
committerMiguel <m.i@gmx.at>2025-01-19 02:11:50 +0100
commitaff0bc0d784c42f917822a126e0cbc583f5525dd (patch)
tree3d960438e00cc65595f2f93d31048610c1f77ed5 /main.cpp
parent526a889171dad5c1654d20c911df17917a2b6a6f (diff)
recreate swap chain on resize etc
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp70
1 files changed, 57 insertions, 13 deletions
diff --git a/main.cpp b/main.cpp
index cef5ea4..2e01744 100644
--- a/main.cpp
+++ b/main.cpp
@@ -85,6 +85,8 @@ private:
}
bool quit=false;
+ bool framebufferResized = false;
+
GLFWwindow* window;
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
@@ -122,11 +124,15 @@ private:
void initWindow() {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); // no OpenGL
- glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); // no resizing
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetWindowUserPointer(window, this);
glfwSetKeyCallback(window, key_callback);
- glfwSetWindowPos(window, 1000, 1000);
+ glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
+ }
+
+ static void framebufferResizeCallback(GLFWwindow* window, int width, int height) {
+ std::cout << "resized" << std::endl;
+ static_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window))->framebufferResized = true;
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
@@ -526,6 +532,34 @@ private:
}
}
+ void recreateSwapChain() {
+ int width = 0, height = 0;
+ glfwGetFramebufferSize(window, &width, &height);
+ while (width == 0 || height == 0) {
+ std::cout << "frame buffer size 0x0" << std::endl;
+ glfwWaitEvents();
+ glfwGetFramebufferSize(window, &width, &height);
+ }
+ std::cout << "recreating swap chain" << std::endl;
+ vkDeviceWaitIdle(device);
+ cleanupSwapChain();
+ createSwapChain();
+ createImageViews();
+ createFramebuffers();
+ }
+
+ void cleanupSwapChain() {
+ for (auto framebuffer : swapChainFramebuffers) {
+ vkDestroyFramebuffer(device, framebuffer, nullptr);
+ }
+
+ for (auto imageView : swapChainImageViews) {
+ vkDestroyImageView(device, imageView, nullptr);
+ }
+
+ vkDestroySwapchainKHR(device, swapChain, nullptr);
+ }
+
void createSwapChain() {
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
@@ -705,10 +739,20 @@ private:
void drawFrame() {
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
- vkResetFences(device, 1, &inFlightFences[currentFrame]);
uint32_t imageIndex;
- vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
+ VkResult result;
+
+ result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
+ if (result == VK_ERROR_OUT_OF_DATE_KHR) {
+ recreateSwapChain();
+ return;
+ } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
+ throw std::runtime_error("failed to acquire swap chain image!");
+ }
+
+ vkResetFences(device, 1, &inFlightFences[currentFrame]);
+
vkResetCommandBuffer(commandBuffers[currentFrame], 0);
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
@@ -740,7 +784,14 @@ private:
presentInfo.pImageIndices = &imageIndex;
presentInfo.pResults = nullptr; // Optional
- vkQueuePresentKHR(presentQueue, &presentInfo);
+ result = vkQueuePresentKHR(presentQueue, &presentInfo);
+
+ if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
+ framebufferResized = false;
+ recreateSwapChain();
+ } else if (result != VK_SUCCESS) {
+ throw std::runtime_error("failed to present swap chain image!");
+ }
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
}
@@ -975,18 +1026,11 @@ private:
vkDestroyFence(device, inFlightFences[i], nullptr);
}
vkDestroyCommandPool(device, commandPool, nullptr);
- for (auto framebuffer : swapChainFramebuffers) {
- vkDestroyFramebuffer(device, framebuffer, nullptr);
- }
+ cleanupSwapChain();
vkDestroyPipeline(device, graphicsPipeline, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyRenderPass(device, renderPass, nullptr);
- for (auto imageView : swapChainImageViews) {
- vkDestroyImageView(device, imageView, nullptr);
- }
- vkDestroySwapchainKHR(device, swapChain, nullptr);
vkDestroyDevice(device, nullptr);
-
if (enableValidationLayers) {
DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
}