Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision f5d5686168e47cbab6259ae2addd03d7f505575e)
+++ vulkan-game.cpp	(revision 621664a0d2a1afd3b718c92268ecf3442ffe0bca)
@@ -97,7 +97,7 @@
 
 struct UniformBufferObject {
-   glm::mat4 model;
-   glm::mat4 view;
-   glm::mat4 proj;
+   alignas(16) glm::mat4 model;
+   alignas(16) glm::mat4 view;
+   alignas(16) glm::mat4 proj;
 };
 
@@ -110,5 +110,5 @@
 
 const vector<uint16_t> indices = {
-   0, 1, 2, 2, 3, 0 
+   0, 1, 2, 2, 3, 0
 };
 
@@ -117,6 +117,5 @@
       const VkAllocationCallbacks* pAllocator,
       VkDebugUtilsMessengerEXT* pDebugMessenger) {
-   auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
-      instance, "vkCreateDebugUtilsMessengerEXT");
+   auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
 
    if (func != nullptr) {
@@ -130,6 +129,5 @@
       VkDebugUtilsMessengerEXT debugMessenger,
       const VkAllocationCallbacks* pAllocator) {
-   auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
-      instance, "vkDestroyDebugUtilsMessengerEXT");
+   auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
 
    if (func != nullptr) {
@@ -148,4 +146,5 @@
          cleanup();
       }
+
    private:
       GameGui* gui = new GameGui_SDL();
@@ -167,6 +166,7 @@
       VkFormat swapChainImageFormat;
       VkExtent2D swapChainExtent;
-
       vector<VkImageView> swapChainImageViews;
+      vector<VkFramebuffer> swapChainFramebuffers;
+
       VkRenderPass renderPass;
       VkDescriptorSetLayout descriptorSetLayout;
@@ -190,5 +190,4 @@
       vector<VkDeviceMemory> uniformBuffersMemory;
 
-      vector<VkFramebuffer> swapChainFramebuffers;
       vector<VkCommandBuffer> commandBuffers;
 
@@ -240,54 +239,4 @@
       }
 
-      void recreateSwapChain() {
-         int width = 0, height = 0;
-         gui->GetWindowSize(&width, &height);
-
-         while (width == 0 || height == 0 ||
-            (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0) {
-            SDL_WaitEvent(nullptr);
-            gui->GetWindowSize(&width, &height);
-         }
-
-         vkDeviceWaitIdle(device);
-
-         cleanupSwapChain();
-
-         createSwapChain();
-         createImageViews();
-         createRenderPass();
-         createGraphicsPipeline();
-         createFramebuffers();
-         createUniformBuffers();
-         createDescriptorPool();
-         createDescriptorSets();
-         createCommandBuffers();
-      }
-
-      void cleanupSwapChain() {
-         for (auto framebuffer : swapChainFramebuffers) {
-            vkDestroyFramebuffer(device, framebuffer, nullptr);
-         }
-
-         vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
-
-         vkDestroyPipeline(device, graphicsPipeline, nullptr);
-         vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
-         vkDestroyRenderPass(device, renderPass, nullptr);
-
-         for (auto imageView : swapChainImageViews) {
-            vkDestroyImageView(device, imageView, nullptr);
-         }
-
-         vkDestroySwapchainKHR(device, swapChain, nullptr);
-
-         for (size_t i = 0; i < swapChainImages.size(); i++) {
-            vkDestroyBuffer(device, uniformBuffers[i], nullptr);
-            vkFreeMemory(device, uniformBuffersMemory[i], nullptr);
-         }
-
-         vkDestroyDescriptorPool(device, descriptorPool, nullptr);
-      }
-
       void createInstance() {
          if (enableValidationLayers && !checkValidationLayerSupport()) {
@@ -335,4 +284,39 @@
       }
 
+      bool checkValidationLayerSupport() {
+         uint32_t layerCount;
+         vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
+
+         vector<VkLayerProperties> availableLayers(layerCount);
+         vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
+
+         for (const char* layerName : validationLayers) {
+            bool layerFound = false;
+
+            for (const auto& layerProperties : availableLayers) {
+               if (strcmp(layerName, layerProperties.layerName) == 0) {
+                  layerFound = true;
+                  break;
+               }
+            }
+
+            if (!layerFound) {
+               return false;
+            }
+         }
+
+         return true;
+      }
+
+      vector<const char*> getRequiredExtensions() {
+         vector<const char*> extensions = gui->GetRequiredExtensions();
+
+         if (enableValidationLayers) {
+            extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+         }
+
+         return extensions;
+      }
+
       void setupDebugMessenger() {
          if (!enableValidationLayers) return;
@@ -342,6 +326,14 @@
 
          if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
-            throw runtime_error("failed to setup debug messenger!");
-         }
+            throw runtime_error("failed to set up debug messenger!");
+         }
+      }
+
+      void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) {
+         createInfo = {};
+         createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
+         createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+         createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+         createInfo.pfnUserCallback = debugCallback;
       }
 
@@ -350,5 +342,5 @@
 
          if (sdlSurface == nullptr) {
-             cout << "Could not get SDL Surface! =(" << endl;
+            cout << "Could not get SDL Surface! =(" << endl;
          }
 
@@ -393,7 +385,5 @@
 
          QueueFamilyIndices indices = findQueueFamilies(device);
-
          bool extensionsSupported = checkDeviceExtensionSupport(device);
-
          bool swapChainAdequate = false;
 
@@ -431,5 +421,4 @@
          for (uint32_t queueFamily : uniqueQueueFamilies) {
             VkDeviceQueueCreateInfo queueCreateInfo = {};
-
             queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
             queueCreateInfo.queueFamilyIndex = queueFamily;
@@ -444,6 +433,5 @@
          VkDeviceCreateInfo createInfo = {};
          createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
-
-         createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());;
+         createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
          createInfo.pQueueCreateInfos = queueCreateInfos.data();
 
@@ -470,146 +458,4 @@
       }
 
-      bool checkValidationLayerSupport() {
-         uint32_t layerCount;
-         vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
-
-         vector<VkLayerProperties> availableLayers(layerCount);
-         vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
-
-         for (const char* layerName : validationLayers) {
-            bool layerFound = false;
-
-            for (const auto& layerProperties : availableLayers) {
-               if (strcmp(layerName, layerProperties.layerName) == 0) {
-                  layerFound = true;
-                  break;
-               }
-            }
-
-            if (!layerFound) {
-               return false;
-            }
-         }
-
-         return true;
-      }
-
-      QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
-         QueueFamilyIndices indices;
-
-         uint32_t queueFamilyCount = 0;
-         vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
-
-         vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
-         vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
-
-         int i = 0;
-         for (const auto& queueFamily : queueFamilies) {
-            if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
-               indices.graphicsFamily = i;
-            }
-
-            VkBool32 presentSupport = false;
-            vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
-
-            if (queueFamily.queueCount > 0 && presentSupport) {
-               indices.presentFamily = i;
-            }
-
-            if (indices.isComplete()) {
-               break;
-            }
-
-            i++;
-         }
-
-         return indices;
-      }
-
-      SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) {
-         SwapChainSupportDetails details;
-
-         vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
-
-         uint32_t formatCount;
-         vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
-
-         if (formatCount != 0) {
-            details.formats.resize(formatCount);
-            vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
-         }
-
-         uint32_t presentModeCount;
-         vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
-
-         if (presentModeCount != 0) {
-            details.presentModes.resize(presentModeCount);
-            vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
-         }
-
-         return details;
-      }
-
-      VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats) {
-         for (const auto& availableFormat : availableFormats) {
-            if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
-               return availableFormat;
-            }
-         }
-
-         return availableFormats[0];
-      }
-
-      VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes) {
-         VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
-
-         for (const auto& availablePresentMode : availablePresentModes) {
-            if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
-               return availablePresentMode;
-            } else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
-               bestMode = availablePresentMode;
-            }
-         }
-
-         return bestMode;
-      }
-
-      VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
-         if (capabilities.currentExtent.width != numeric_limits<uint32_t>::max()) {
-            return capabilities.currentExtent;
-         } else {
-            int width, height;
-            gui->GetWindowSize(&width, &height);
-
-            VkExtent2D actualExtent = {
-               static_cast<uint32_t>(width),
-               static_cast<uint32_t>(height)
-            };
-
-            actualExtent.width = max(capabilities.minImageExtent.width, min(capabilities.maxImageExtent.width, actualExtent.width));
-            actualExtent.height = max(capabilities.minImageExtent.height, min(capabilities.maxImageExtent.height, actualExtent.height));
-
-            return actualExtent;
-         }
-      }
-
-      void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) {
-         createInfo = {};
-         createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
-         createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
-         createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
-         createInfo.pfnUserCallback = debugCallback;
-      }
-
-      vector<const char*> getRequiredExtensions() {
-         vector<const char*> extensions = gui->GetRequiredExtensions();
-
-         if (enableValidationLayers) {
-            extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
-         }
-
-         return extensions;
-      }
-
       void createSwapChain() {
          SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
@@ -620,11 +466,9 @@
 
          uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
-         if (swapChainSupport.capabilities.maxImageCount > 0 &&
-               imageCount > swapChainSupport.capabilities.maxImageCount) {
+         if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) {
             imageCount = swapChainSupport.capabilities.maxImageCount;
          }
 
          VkSwapchainCreateInfoKHR createInfo = {};
-
          createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
          createInfo.surface = surface;
@@ -645,5 +489,5 @@
          } else {
             createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
-            createInfo.queueFamilyIndexCount = 0; // Optional
+            createInfo.queueFamilyIndexCount = 0;
             createInfo.pQueueFamilyIndices = nullptr;
          }
@@ -667,12 +511,80 @@
       }
 
+      SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) {
+         SwapChainSupportDetails details;
+
+         vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
+
+         uint32_t formatCount;
+         vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
+
+         if (formatCount != 0) {
+            details.formats.resize(formatCount);
+            vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
+         }
+
+         uint32_t presentModeCount;
+         vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
+
+         if (presentModeCount != 0) {
+            details.presentModes.resize(presentModeCount);
+            vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
+         }
+
+         return details;
+      }
+
+      VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats) {
+         for (const auto& availableFormat : availableFormats) {
+            if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
+               return availableFormat;
+            }
+         }
+
+         return availableFormats[0];
+      }
+
+      VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes) {
+         VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
+
+         for (const auto& availablePresentMode : availablePresentModes) {
+            if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
+               return availablePresentMode;
+            }
+            else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
+               bestMode = availablePresentMode;
+            }
+         }
+
+         return bestMode;
+      }
+
+      VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
+         if (capabilities.currentExtent.width != numeric_limits<uint32_t>::max()) {
+            return capabilities.currentExtent;
+         }
+         else {
+            int width, height;
+            gui->GetWindowSize(&width, &height);
+
+            VkExtent2D actualExtent = {
+               static_cast<uint32_t>(width),
+               static_cast<uint32_t>(height)
+            };
+
+            actualExtent.width = max(capabilities.minImageExtent.width, min(capabilities.maxImageExtent.width, actualExtent.width));
+            actualExtent.height = max(capabilities.minImageExtent.height, min(capabilities.maxImageExtent.height, actualExtent.height));
+
+            return actualExtent;
+         }
+      }
+
       void createImageViews() {
          swapChainImageViews.resize(swapChainImages.size());
 
-         for (size_t i=0; i<swapChainImages.size(); i++) {
+         for (size_t i = 0; i < swapChainImages.size(); i++) {
             VkImageViewCreateInfo createInfo = {};
             createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
             createInfo.image = swapChainImages[i];
-
             createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
             createInfo.format = swapChainImageFormat;
@@ -715,5 +627,5 @@
          subpass.pColorAttachments = &colorAttachmentRef;
 
-         VkSubpassDependency  dependency = {};
+         VkSubpassDependency dependency = {};
          dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
          dependency.dstSubpass = 0;
@@ -819,5 +731,5 @@
          rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
          rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
-         rasterizer.depthBiasEnable = false;
+         rasterizer.depthBiasEnable = VK_FALSE;
 
          VkPipelineMultisampleStateCreateInfo multisampling = {};
@@ -923,6 +835,38 @@
 
          if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
-            throw runtime_error("failed to create command pool!");
-         }
+            throw runtime_error("failed to create graphics command pool!");
+         }
+      }
+
+      QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
+         QueueFamilyIndices indices;
+
+         uint32_t queueFamilyCount = 0;
+         vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
+
+         vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
+         vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
+
+         int i = 0;
+         for (const auto& queueFamily : queueFamilies) {
+            if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+               indices.graphicsFamily = i;
+            }
+
+            VkBool32 presentSupport = false;
+            vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
+
+            if (queueFamily.queueCount > 0 && presentSupport) {
+               indices.presentFamily = i;
+            }
+
+            if (indices.isComplete()) {
+               break;
+            }
+
+            i++;
+         }
+
+         return indices;
       }
 
@@ -964,7 +908,6 @@
       }
 
-      void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
-            VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image,
-            VkDeviceMemory& imageMemory) {
+      void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage,
+            VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory) {
          VkImageCreateInfo imageInfo = {};
          imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@@ -989,5 +932,5 @@
          vkGetImageMemoryRequirements(device, image, &memRequirements);
 
-         VkMemoryAllocateInfo allocInfo;
+         VkMemoryAllocateInfo allocInfo = {};
          allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
          allocInfo.allocationSize = memRequirements.size;
@@ -1001,6 +944,5 @@
       }
 
-      void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout,
-            VkImageLayout newLayout) {
+      void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) {
          VkCommandBuffer commandBuffer = beginSingleTimeCommands();
 
@@ -1080,5 +1022,5 @@
          VkBuffer stagingBuffer;
          VkDeviceMemory stagingBufferMemory;
-         createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 
+         createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
             stagingBuffer, stagingBufferMemory);
@@ -1086,5 +1028,5 @@
          void* data;
          vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
-         memcpy(data, vertices.data(), (size_t)bufferSize);
+         memcpy(data, vertices.data(), (size_t) bufferSize);
          vkUnmapMemory(device, stagingBufferMemory);
 
@@ -1109,5 +1051,5 @@
          void* data;
          vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
-         memcpy(data, indices.data(), (size_t)bufferSize);
+         memcpy(data, indices.data(), (size_t) bufferSize);
          vkUnmapMemory(device, stagingBufferMemory);
 
@@ -1121,6 +1063,18 @@
       }
 
-      void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties,
-            VkBuffer& buffer, VkDeviceMemory& bufferMemory) {
+      void createUniformBuffers() {
+         VkDeviceSize bufferSize = sizeof(UniformBufferObject);
+
+         uniformBuffers.resize(swapChainImages.size());
+         uniformBuffersMemory.resize(swapChainImages.size());
+
+         for (size_t i = 0; i < swapChainImages.size(); i++) {
+            createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+               VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+               uniformBuffers[i], uniformBuffersMemory[i]);
+         }
+      }
+
+      void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) {
          VkBufferCreateInfo bufferInfo = {};
          bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@@ -1140,5 +1094,5 @@
          allocInfo.allocationSize = memRequirements.size;
          allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
-      
+
          if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
             throw runtime_error("failed to allocate buffer memory!");
@@ -1204,17 +1158,4 @@
       }
 
-      void createUniformBuffers() {
-         VkDeviceSize bufferSize = sizeof(UniformBufferObject);
-
-         uniformBuffers.resize(swapChainImages.size());
-         uniformBuffersMemory.resize(swapChainImages.size());
-
-         for (size_t i = 0; i < swapChainImages.size(); i++) {
-            createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
-               VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-               uniformBuffers[i], uniformBuffersMemory[i]);
-         }
-      }
-
       void createDescriptorPool() {
          VkDescriptorPoolSize poolSize = {};
@@ -1235,4 +1176,5 @@
       void createDescriptorSets() {
          vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), descriptorSetLayout);
+
          VkDescriptorSetAllocateInfo allocInfo = {};
          allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
@@ -1274,8 +1216,8 @@
          allocInfo.commandPool = commandPool;
          allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-         allocInfo.commandBufferCount = (uint32_t)commandBuffers.size();
+         allocInfo.commandBufferCount = (uint32_t) commandBuffers.size();
 
          if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) {
-            throw runtime_error("failed to create command buffers!");
+            throw runtime_error("failed to allocate command buffers!");
          }
 
@@ -1302,4 +1244,5 @@
 
             vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
+
             vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
 
@@ -1312,4 +1255,5 @@
 
             vkCmdDrawIndexed(commandBuffers[i], static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
+
             vkCmdEndRenderPass(commandBuffers[i]);
 
@@ -1380,5 +1324,6 @@
          uint32_t imageIndex;
 
-         VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(), imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
+         VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(),
+            imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
 
          if (result == VK_ERROR_OUT_OF_DATE_KHR) {
@@ -1416,5 +1361,4 @@
          VkPresentInfoKHR presentInfo = {};
          presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
-
          presentInfo.waitSemaphoreCount = 1;
          presentInfo.pWaitSemaphores = signalSemaphores;
@@ -1447,5 +1391,5 @@
          ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
          ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
-         ubo.proj = glm::perspective(glm::radians(45.0f), swapChainExtent.width / (float) swapChainExtent.height, 0.1f, 10.0f);
+         ubo.proj = glm::perspective(glm::radians(45.0f), swapChainExtent.width / (float)swapChainExtent.height, 0.1f, 10.0f);
          ubo.proj[1][1] *= -1;
 
@@ -1456,4 +1400,30 @@
       }
 
+      void recreateSwapChain() {
+         int width = 0, height = 0;
+
+         gui->GetWindowSize(&width, &height);
+
+         while (width == 0 || height == 0 ||
+            (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0) {
+            SDL_WaitEvent(nullptr);
+            gui->GetWindowSize(&width, &height);
+         }
+
+         vkDeviceWaitIdle(device);
+
+         cleanupSwapChain();
+
+         createSwapChain();
+         createImageViews();
+         createRenderPass();
+         createGraphicsPipeline();
+         createFramebuffers();
+         createUniformBuffers();
+         createDescriptorPool();
+         createDescriptorSets();
+         createCommandBuffers();
+      }
+
       void cleanup() {
          cleanupSwapChain();
@@ -1471,6 +1441,6 @@
 
          for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
+            vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
             vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
-            vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
             vkDestroyFence(device, inFlightFences[i], nullptr);
          }
@@ -1492,9 +1462,34 @@
       }
 
+      void cleanupSwapChain() {
+         for (auto framebuffer : swapChainFramebuffers) {
+            vkDestroyFramebuffer(device, framebuffer, nullptr);
+         }
+
+         vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
+
+         vkDestroyPipeline(device, graphicsPipeline, nullptr);
+         vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
+         vkDestroyRenderPass(device, renderPass, nullptr);
+
+         for (auto imageView : swapChainImageViews) {
+            vkDestroyImageView(device, imageView, nullptr);
+         }
+
+         vkDestroySwapchainKHR(device, swapChain, nullptr);
+
+         for (size_t i = 0; i < swapChainImages.size(); i++) {
+            vkDestroyBuffer(device, uniformBuffers[i], nullptr);
+            vkFreeMemory(device, uniformBuffersMemory[i], nullptr);
+         }
+
+         vkDestroyDescriptorPool(device, descriptorPool, nullptr);
+      }
+
       static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
-         VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
-         VkDebugUtilsMessageTypeFlagsEXT messageType,
-         const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
-         void* pUserData) {
+            VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+            VkDebugUtilsMessageTypeFlagsEXT messageType,
+            const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
+            void* pUserData) {
          cerr << "validation layer: " << pCallbackData->pMessage << endl;
 
@@ -1509,5 +1504,5 @@
          }
 
-         size_t fileSize = (size_t)file.tellg();
+         size_t fileSize = (size_t) file.tellg();
          vector<char> buffer(fileSize);
 
