Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision d25381b88830bd62aa0ed8ef68e8641eff248736)
+++ vulkan-game.cpp	(revision 860a0da7bda4763e3a1be95cfde80564e1cc9319)
@@ -194,4 +194,25 @@
    initGraphicsPipelines();
 
+   overlayPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos));
+   overlayPipeline.addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&OverlayVertex::texCoord));
+
+   overlayPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+      VK_SHADER_STAGE_FRAGMENT_BIT, &sdlOverlayImageDescriptor);
+
+   addObject(overlayObjects, overlayPipeline,
+      {
+         {{-1.0f,  1.0f,  0.0f}, {0.0f, 1.0f}},
+         {{ 1.0f,  1.0f,  0.0f}, {1.0f, 1.0f}},
+         {{ 1.0f, -1.0f,  0.0f}, {1.0f, 0.0f}},
+         {{-1.0f, -1.0f,  0.0f}, {0.0f, 0.0f}}
+      }, {
+         0, 1, 2, 2, 3, 0
+      }, {});
+
+   overlayPipeline.createDescriptorSetLayout();
+   overlayPipeline.createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
+   overlayPipeline.createDescriptorPool(swapChainImages);
+   overlayPipeline.createDescriptorSets(swapChainImages);
+
    modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::pos));
    modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::color));
@@ -201,12 +222,8 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
-   // TODO: Calculate the size of this buffer (and all the other SSBOs) based on the number of objects
-   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-      storageBuffers_modelPipeline, storageBuffersMemory_modelPipeline, storageBufferInfoList_modelPipeline);
 
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
-   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &storageBufferInfoList_modelPipeline);
+   modelPipeline.addStorageDescriptor();
 
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
@@ -242,25 +259,4 @@
    modelPipeline.createDescriptorSets(swapChainImages);
 
-   overlayPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos));
-   overlayPipeline.addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&OverlayVertex::texCoord));
-
-   overlayPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-      VK_SHADER_STAGE_FRAGMENT_BIT, &sdlOverlayImageDescriptor);
-
-   addObject(overlayObjects, overlayPipeline,
-      {
-         {{-1.0f,  1.0f,  0.0f}, {0.0f, 1.0f}},
-         {{ 1.0f,  1.0f,  0.0f}, {1.0f, 1.0f}},
-         {{ 1.0f, -1.0f,  0.0f}, {1.0f, 0.0f}},
-         {{-1.0f, -1.0f,  0.0f}, {0.0f, 0.0f}}
-      }, {
-         0, 1, 2, 2, 3, 0
-      }, {});
-
-   overlayPipeline.createDescriptorSetLayout();
-   overlayPipeline.createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
-   overlayPipeline.createDescriptorPool(swapChainImages);
-   overlayPipeline.createDescriptorSets(swapChainImages);
-
    shipPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ShipVertex::pos));
    shipPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ShipVertex::color));
@@ -270,11 +266,8 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
-   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-      storageBuffers_shipPipeline, storageBuffersMemory_shipPipeline, storageBufferInfoList_shipPipeline);
 
    shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_shipPipeline);
-   shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &storageBufferInfoList_shipPipeline);
+   shipPipeline.addStorageDescriptor();
 
    // TODO: With the normals, indexing basically becomes pointless since no vertices will have exactly
@@ -526,11 +519,8 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
-   createBufferSet(10 * sizeof(SSBO_Asteroid), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-      storageBuffers_asteroidPipeline, storageBuffersMemory_asteroidPipeline, storageBufferInfoList_asteroidPipeline);
 
    asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_asteroidPipeline);
-   asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &storageBufferInfoList_asteroidPipeline);
+   asteroidPipeline.addStorageDescriptor();
 
    addObject(asteroidObjects, asteroidPipeline,
@@ -631,14 +621,14 @@
 void VulkanGame::initGraphicsPipelines() {
    overlayPipeline = GraphicsPipeline_Vulkan<OverlayVertex, void*>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 4, 6);
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 4, 6, 0);
 
    modelPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 16, 24);
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 16, 24, 10);
 
    shipPipeline = GraphicsPipeline_Vulkan<ShipVertex, SSBO_ModelObject>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 138, 138);
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 138, 138, 10);
 
    asteroidPipeline = GraphicsPipeline_Vulkan<AsteroidVertex, SSBO_Asteroid>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 24, 36);
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 36, 10);
 }
 
@@ -790,5 +780,5 @@
 
    for (size_t i = 0; i < modelObjects.size(); i++) {
-      VulkanUtils::copyDataToMemory(device, storageBuffersMemory_modelPipeline[currentImage],
+      VulkanUtils::copyDataToMemory(device, modelPipeline.storageBufferSet.memory[currentImage],
          i, so_Object);
    }
@@ -796,9 +786,9 @@
    VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_shipPipeline[currentImage], 0, ship_VP_mats);
 
-   VulkanUtils::copyDataToMemory(device, storageBuffersMemory_shipPipeline[currentImage], 0, so_Ship);
+   VulkanUtils::copyDataToMemory(device, shipPipeline.storageBufferSet.memory[currentImage], 0, so_Ship);
 
    VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_asteroidPipeline[currentImage], 0, asteroid_VP_mats);
 
-   VulkanUtils::copyDataToMemory(device, storageBuffersMemory_asteroidPipeline[currentImage], 0, so_Asteroid);
+   VulkanUtils::copyDataToMemory(device, asteroidPipeline.storageBufferSet.memory[currentImage], 0, so_Asteroid);
 }
 
@@ -1461,6 +1451,4 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
-   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-      storageBuffers_modelPipeline, storageBuffersMemory_modelPipeline, storageBufferInfoList_modelPipeline);
 
    modelPipeline.updateRenderPass(renderPass);
@@ -1476,6 +1464,4 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
-   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-      storageBuffers_shipPipeline, storageBuffersMemory_shipPipeline, storageBufferInfoList_shipPipeline);
 
    shipPipeline.updateRenderPass(renderPass);
@@ -1486,6 +1472,4 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
-   createBufferSet(10 * sizeof(SSBO_Asteroid), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-      storageBuffers_asteroidPipeline, storageBuffersMemory_asteroidPipeline, storageBufferInfoList_asteroidPipeline);
 
    asteroidPipeline.updateRenderPass(renderPass);
@@ -1506,16 +1490,8 @@
    vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
 
+   overlayPipeline.cleanup();
    modelPipeline.cleanup();
-   overlayPipeline.cleanup();
    shipPipeline.cleanup();
    asteroidPipeline.cleanup();
-
-   vkDestroyRenderPass(device, renderPass, nullptr);
-
-   for (VkImageView imageView : swapChainImageViews) {
-      vkDestroyImageView(device, imageView, nullptr);
-   }
-
-   vkDestroySwapchainKHR(device, swapChain, nullptr);
 
    for (size_t i = 0; i < uniformBuffers_modelPipeline.size(); i++) {
@@ -1524,9 +1500,4 @@
    }
 
-   for (size_t i = 0; i < storageBuffers_modelPipeline.size(); i++) {
-      vkDestroyBuffer(device, storageBuffers_modelPipeline[i], nullptr);
-      vkFreeMemory(device, storageBuffersMemory_modelPipeline[i], nullptr);
-   }
-
    for (size_t i = 0; i < uniformBuffers_shipPipeline.size(); i++) {
       vkDestroyBuffer(device, uniformBuffers_shipPipeline[i], nullptr);
@@ -1534,9 +1505,4 @@
    }
 
-   for (size_t i = 0; i < storageBuffers_shipPipeline.size(); i++) {
-      vkDestroyBuffer(device, storageBuffers_shipPipeline[i], nullptr);
-      vkFreeMemory(device, storageBuffersMemory_shipPipeline[i], nullptr);
-   }
-
    for (size_t i = 0; i < uniformBuffers_asteroidPipeline.size(); i++) {
       vkDestroyBuffer(device, uniformBuffers_asteroidPipeline[i], nullptr);
@@ -1544,7 +1510,10 @@
    }
 
-   for (size_t i = 0; i < storageBuffers_asteroidPipeline.size(); i++) {
-      vkDestroyBuffer(device, storageBuffers_asteroidPipeline[i], nullptr);
-      vkFreeMemory(device, storageBuffersMemory_asteroidPipeline[i], nullptr);
-   }
-}
+   vkDestroyRenderPass(device, renderPass, nullptr);
+
+   for (VkImageView imageView : swapChainImageViews) {
+      vkDestroyImageView(device, imageView, nullptr);
+   }
+
+   vkDestroySwapchainKHR(device, swapChain, nullptr);
+}
