Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 737c26a42ae28afe045783b70f83953f2aee5cdd)
+++ vulkan-game.cpp	(revision 1cb64e6d2b6196f60400c2e21cc3d1a265874635)
@@ -56,20 +56,20 @@
    // Also, decide whether to use this-> for all instance variables, or only when necessary
 
-   this->debugMessenger = VK_NULL_HANDLE;
-
-   this->gui = nullptr;
-   this->window = nullptr;
-
-   this->swapChainPresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
-   this->swapChainMinImageCount = 0;
-
-   this->currentFrame = 0;
+   debugMessenger = VK_NULL_HANDLE;
+
+   gui = nullptr;
+   window = nullptr;
+
+   swapChainPresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
+   swapChainMinImageCount = 0;
+
+   currentFrame = 0;
    shouldRecreateSwapChain = false;
 
-   this->object_VP_mats = {};
-   this->ship_VP_mats = {};
-   this->asteroid_VP_mats = {};
-   this->laser_VP_mats = {};
-   this->explosion_UBO = {};
+   object_VP_mats = {};
+   ship_VP_mats = {};
+   asteroid_VP_mats = {};
+   laser_VP_mats = {};
+   explosion_UBO = {};
 }
 
@@ -108,4 +108,6 @@
    currentScreen->init();
 
+   // TODO: Maybe just set shouldRecreateSwapChain to true instead. Check this render loop logic
+   // to make sure there'd be no issues
    recreateSwapChain();
 }
@@ -218,4 +220,5 @@
    createImageViews();
    createRenderPass();
+
    createResourceCommandPool();
    createCommandPools();
@@ -1141,7 +1144,5 @@
 
 void VulkanGame::cleanup() {
-   if (vkDeviceWaitIdle(device) != VK_SUCCESS) {
-      throw runtime_error("failed to wait for device!");
-   }
+   VKUTIL_CHECK_RESULT(vkDeviceWaitIdle(device), "failed to wait for device!");
 
    ImGui_ImplVulkan_Shutdown();
@@ -1281,4 +1282,5 @@
    cerr << "validation layer: " << pCallbackData->pMessage << endl;
 
+   // TODO: Figure out what the return value means and if it should always be VK_FALSE
    return VK_FALSE;
 }
@@ -1683,66 +1685,4 @@
       }
    }
-
-   for (size_t i = 0; i < commandBuffers.size(); i++) {
-      VkCommandBufferBeginInfo beginInfo = {};
-      beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-      beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
-      beginInfo.pInheritanceInfo = nullptr;
-
-      if (vkBeginCommandBuffer(commandBuffers[i], &beginInfo) != VK_SUCCESS) {
-         throw runtime_error("failed to begin recording command buffer!");
-      }
-
-      VkRenderPassBeginInfo renderPassInfo = {};
-      renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
-      renderPassInfo.renderPass = renderPass;
-      renderPassInfo.framebuffer = swapChainFramebuffers[i];
-      renderPassInfo.renderArea.offset = { 0, 0 };
-      renderPassInfo.renderArea.extent = swapChainExtent;
-
-      array<VkClearValue, 2> clearValues = {};
-      clearValues[0].color = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
-      clearValues[1].depthStencil = { 1.0f, 0 };
-
-      renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
-      renderPassInfo.pClearValues = clearValues.data();
-
-      vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
-
-      currentScreen->createRenderCommands(commandBuffers[i], i);
-
-      /**********************************************************/
-
-      ImGui_ImplVulkan_NewFrame();
-      ImGui_ImplSDL2_NewFrame(this->window);
-      ImGui::NewFrame();
-
-      {
-         ImGui::SetNextWindowSize(ImVec2(250, 35), ImGuiCond_Once);
-         ImGui::SetNextWindowPos(ImVec2(380, 10), ImGuiCond_Once);
-         ImGui::Begin("WndMenubar", NULL,
-            ImGuiWindowFlags_NoTitleBar |
-            ImGuiWindowFlags_NoResize |
-            ImGuiWindowFlags_NoMove);
-         ImGui::InvisibleButton("", ImVec2(155, 18));
-         ImGui::SameLine();
-         if (ImGui::Button("Main Menu")) {
-            cout << "Clicked on the main button" << endl;
-            //events.push(Event::GO_TO_MAIN_MENU);
-         }
-         ImGui::End();
-      }
-
-      ImGui::Render();
-      ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffers[i]);
-
-      /**********************************************************/
-
-      vkCmdEndRenderPass(commandBuffers[i]);
-
-      if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) {
-         throw runtime_error("failed to record command buffer!");
-      }
-   }
 }
 
@@ -1766,4 +1706,67 @@
 
    updateScene();
+
+   VKUTIL_CHECK_RESULT(vkResetCommandPool(device, commandPools[imageIndex], 0),
+      "failed to reset command pool!");
+
+   VkCommandBufferBeginInfo beginInfo = {};
+   beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+   beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
+   beginInfo.pInheritanceInfo = nullptr;
+
+   if (vkBeginCommandBuffer(commandBuffers[imageIndex], &beginInfo) != VK_SUCCESS) {
+      throw runtime_error("failed to begin recording command buffer!");
+   }
+
+   VkRenderPassBeginInfo renderPassInfo = {};
+   renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+   renderPassInfo.renderPass = renderPass;
+   renderPassInfo.framebuffer = swapChainFramebuffers[imageIndex];
+   renderPassInfo.renderArea.offset = { 0, 0 };
+   renderPassInfo.renderArea.extent = swapChainExtent;
+
+   array<VkClearValue, 2> clearValues = {};
+   clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
+   clearValues[1].depthStencil = { 1.0f, 0 };
+
+   renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
+   renderPassInfo.pClearValues = clearValues.data();
+
+   vkCmdBeginRenderPass(commandBuffers[imageIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+   currentScreen->createRenderCommands(commandBuffers[imageIndex], imageIndex);
+
+   /**********************************************************/
+
+   ImGui_ImplVulkan_NewFrame();
+   ImGui_ImplSDL2_NewFrame(this->window);
+   ImGui::NewFrame();
+
+   {
+      ImGui::SetNextWindowSize(ImVec2(250, 35), ImGuiCond_Once);
+      ImGui::SetNextWindowPos(ImVec2(380, 10), ImGuiCond_Once);
+      ImGui::Begin("WndMenubar", NULL,
+         ImGuiWindowFlags_NoTitleBar |
+         ImGuiWindowFlags_NoResize |
+         ImGuiWindowFlags_NoMove);
+      ImGui::InvisibleButton("", ImVec2(155, 18));
+      ImGui::SameLine();
+      if (ImGui::Button("Main Menu")) {
+         cout << "Clicked on the main button" << endl;
+         //events.push(Event::GO_TO_MAIN_MENU);
+      }
+      ImGui::End();
+   }
+
+   ImGui::Render();
+   ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffers[imageIndex]);
+
+   /**********************************************************/
+
+   vkCmdEndRenderPass(commandBuffers[imageIndex]);
+
+   if (vkEndCommandBuffer(commandBuffers[imageIndex]) != VK_SUCCESS) {
+      throw runtime_error("failed to record command buffer!");
+   }
 
    VkSemaphore waitSemaphores[] = { imageAcquiredSemaphores[currentFrame] };
@@ -1781,7 +1784,6 @@
    submitInfo.pSignalSemaphores = signalSemaphores;
 
-   if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]) != VK_SUCCESS) {
-      throw runtime_error("failed to submit draw command buffer!");
-   }
+   VKUTIL_CHECK_RESULT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]),
+      "failed to submit draw command buffer!");
 }
 
@@ -1800,9 +1802,11 @@
    VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
 
-   if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || shouldRecreateSwapChain) {
-      shouldRecreateSwapChain = false;
-      recreateSwapChain();
-   } else if (result != VK_SUCCESS) {
-      throw runtime_error("failed to present swap chain image!");
+   if (result == VK_SUBOPTIMAL_KHR) {
+      shouldRecreateSwapChain = true;
+   } else if (result == VK_ERROR_OUT_OF_DATE_KHR) {
+      shouldRecreateSwapChain = true;
+      return;
+   } else {
+      VKUTIL_CHECK_RESULT(result, "failed to present swap chain image!");
    }
 
@@ -2125,15 +2129,5 @@
 }
 
-// TODO: Fix the crash that happens when alt-tabbing
 void VulkanGame::recreateSwapChain() {
-   cout << "Recreating swap chain" << endl;
-   gui->refreshWindowSize();
-
-   while (gui->getWindowWidth() == 0 || gui->getWindowHeight() == 0 ||
-      (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0) {
-      SDL_WaitEvent(nullptr);
-      gui->refreshWindowSize();
-   }
-
    if (vkDeviceWaitIdle(device) != VK_SUCCESS) {
       throw runtime_error("failed to wait for device!");
