Handling swap chain recreation
This commit is contained in:
@@ -69,6 +69,7 @@ const std::vector<const char*> deviceExtensions = {
|
||||
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||
std::vector<VkFence> inFlightFences;
|
||||
bool framebufferResized = false;
|
||||
|
||||
uint32_t currentFrame = 0;
|
||||
|
||||
@@ -83,9 +84,17 @@ const std::vector<const char*> deviceExtensions = {
|
||||
glfwInit();
|
||||
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
|
||||
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
|
||||
glfwSetWindowUserPointer(window, this);
|
||||
glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
|
||||
}
|
||||
|
||||
|
||||
static void framebufferResizeCallback(GLFWwindow* window, int width, int height) {
|
||||
auto app = reinterpret_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window));
|
||||
app->framebufferResized = true;
|
||||
}
|
||||
|
||||
void initVulkan() {
|
||||
@@ -104,6 +113,41 @@ const std::vector<const char*> deviceExtensions = {
|
||||
createSyncObjects();
|
||||
}
|
||||
|
||||
|
||||
void recreateSwapChain() {
|
||||
int width = 0, height = 0;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
|
||||
while (width == 0 || height == 0) {
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
glfwWaitEvents();
|
||||
}
|
||||
|
||||
|
||||
vkDeviceWaitIdle(device);
|
||||
|
||||
cleanupSwapChain();
|
||||
|
||||
createSwapChain();
|
||||
createImageViews();
|
||||
createFramebuffers();
|
||||
|
||||
}
|
||||
|
||||
void cleanupSwapChain() {
|
||||
for (size_t i = 0; i < swapchainFrameBuffers.size(); i++) {
|
||||
vkDestroyFramebuffer(device, swapchainFrameBuffers[i], nullptr);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
|
||||
vkDestroyImageView(device, swapChainImageViews[i], nullptr);
|
||||
}
|
||||
|
||||
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void createSyncObjects() {
|
||||
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
@@ -867,10 +911,19 @@ const std::vector<const char*> deviceExtensions = {
|
||||
|
||||
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 = 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);
|
||||
@@ -906,14 +959,27 @@ const std::vector<const char*> deviceExtensions = {
|
||||
presentInfo.pSwapchains = swapChains;
|
||||
presentInfo.pImageIndices = &imageIndex;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void cleanup(){
|
||||
cleanupSwapChain();
|
||||
|
||||
|
||||
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||
|
||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
|
||||
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
|
||||
@@ -923,19 +989,6 @@ const std::vector<const char*> deviceExtensions = {
|
||||
|
||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||
|
||||
for (auto framebuffer : swapchainFrameBuffers) {
|
||||
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
||||
}
|
||||
|
||||
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){
|
||||
|
||||
Reference in New Issue
Block a user