Changeset 75108ef in opengl-game


Ignore:
Timestamp:
Jul 19, 2019, 5:59:16 PM (5 years ago)
Author:
Dmitry Portnoy <dmitry.portnoy@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
0e6ecf3
Parents:
47bff4c
Message:

Enable and detect window resizing and recreate the swap chain when it becomes outdated, including when the window is resized

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vulkan-game.cpp

    r47bff4c r75108ef  
    129129      size_t currentFrame = 0;
    130130
     131      bool framebufferResized = false;
     132
    131133      // both SDL and GLFW create window functions return NULL on failure
    132134      bool initWindow() {
     
    142144               SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
    143145               SCREEN_WIDTH, SCREEN_HEIGHT,
    144                SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN);
     146               SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
    145147
    146148            if (window == nullptr) {
     
    169171      }
    170172
     173      void recreateSwapChain() {
     174         int width = 0, height = 0;
     175         SDL_GetWindowSize(window, &width, &height);
     176
     177         while (width == 0 || height == 0 ||
     178            (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0) {
     179            SDL_WaitEvent(nullptr);
     180            SDL_GetWindowSize(window, &width, &height);
     181         }
     182
     183         vkDeviceWaitIdle(device);
     184
     185         cleanupSwapChain();
     186
     187         createSwapChain();
     188         createImageViews();
     189         createRenderPass();
     190         createGraphicsPipeline();
     191         createFramebuffers();
     192         createCommandBuffers();
     193      }
     194
     195      void cleanupSwapChain() {
     196         for (auto framebuffer : swapChainFramebuffers) {
     197            vkDestroyFramebuffer(device, framebuffer, nullptr);
     198         }
     199
     200         vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
     201
     202         vkDestroyPipeline(device, graphicsPipeline, nullptr);
     203         vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
     204         vkDestroyRenderPass(device, renderPass, nullptr);
     205
     206         for (auto imageView : swapChainImageViews) {
     207            vkDestroyImageView(device, imageView, nullptr);
     208         }
     209
     210         vkDestroySwapchainKHR(device, swapChain, nullptr);
     211      }
     212
    171213      void createInstance() {
    172214         if (enableValidationLayers && !checkValidationLayerSupport()) {
     
    464506            return capabilities.currentExtent;
    465507         } else {
    466             VkExtent2D actualExtent = { SCREEN_WIDTH, SCREEN_HEIGHT };
     508            int width, height;
     509            SDL_GetWindowSize(window, &width, &height);
     510
     511            VkExtent2D actualExtent = {
     512               static_cast<uint32_t>(width),
     513               static_cast<uint32_t>(height)
     514            };
    467515
    468516            actualExtent.width = max(capabilities.minImageExtent.width, min(capabilities.maxImageExtent.width, actualExtent.width));
     
    867915                  quit = true;
    868916               }
     917               if (e.type == SDL_WINDOWEVENT) {
     918                  if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
     919                     framebufferResized = true;
     920                  } else if (e.window.event == SDL_WINDOWEVENT_MINIMIZED) {
     921                     framebufferResized = true;
     922                  }
     923               }
    869924            }
    870925
     
    880935      void drawFrame() {
    881936         vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, numeric_limits<uint64_t>::max());
    882          vkResetFences(device, 1, &inFlightFences[currentFrame]);
    883937
    884938         uint32_t imageIndex;
    885939
    886          vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(), imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
     940         VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(), imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
     941
     942         if (result == VK_ERROR_OUT_OF_DATE_KHR) {
     943            recreateSwapChain();
     944            return;
     945         } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
     946            throw runtime_error("failed to acquire swap chain image!");
     947         }
    887948
    888949         VkSubmitInfo submitInfo = {};
     
    903964         submitInfo.pSignalSemaphores = signalSemaphores;
    904965
     966         vkResetFences(device, 1, &inFlightFences[currentFrame]);
     967
    905968         if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
    906969            throw runtime_error("failed to submit draw command buffer!");
     
    919982         presentInfo.pResults = nullptr;
    920983
    921          vkQueuePresentKHR(presentQueue, &presentInfo);
     984         result = vkQueuePresentKHR(presentQueue, &presentInfo);
     985
     986         if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
     987            framebufferResized = false;
     988            recreateSwapChain();
     989         } else if (result != VK_SUCCESS) {
     990            throw runtime_error("failed to present swap chain image!");
     991         }
    922992
    923993         currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
     
    925995
    926996      void cleanup() {
     997         cleanupSwapChain();
     998
    927999         for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
    9281000            vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
     
    9331005         vkDestroyCommandPool(device, commandPool, nullptr);
    9341006
    935          for (auto framebuffer : swapChainFramebuffers) {
    936             vkDestroyFramebuffer(device, framebuffer, nullptr);
    937          }
    938 
    939          vkDestroyPipeline(device, graphicsPipeline, nullptr);
    940          vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
    941          vkDestroyRenderPass(device, renderPass, nullptr);
    942 
    943          for (auto imageView : swapChainImageViews) {
    944             vkDestroyImageView(device, imageView, nullptr);
    945          }
    946 
    947          vkDestroySwapchainKHR(device, swapChain, nullptr);
    9481007         vkDestroyDevice(device, nullptr);
    9491008
Note: See TracChangeset for help on using the changeset viewer.