Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 756162f65401bd12de652b25a35ce6e01efb144a)
+++ vulkan-game.cpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
@@ -119,10 +119,12 @@
    modelPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
 
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
-   modelPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
+   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+      VK_SHADER_STAGE_VERTEX_BIT, &modelPipeline.storageBufferSet.infoSet);
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
@@ -180,10 +182,12 @@
    shipPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
 
    shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_shipPipeline);
-   shipPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
+   shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+      VK_SHADER_STAGE_VERTEX_BIT, &shipPipeline.storageBufferSet.infoSet);
 
    // TODO: With the normals, indexing basically becomes pointless since no vertices will have exactly
@@ -438,10 +442,12 @@
    asteroidPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
 
    asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_asteroidPipeline);
-   asteroidPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
+   asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+      VK_SHADER_STAGE_VERTEX_BIT, &asteroidPipeline.storageBufferSet.infoSet);
 
    asteroidPipeline.createDescriptorSetLayout();
@@ -454,10 +460,12 @@
    laserPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&LaserVertex::objIndex));
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_laserPipeline, uniformBuffersMemory_laserPipeline, uniformBufferInfoList_laserPipeline);
 
    laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_laserPipeline);
-   laserPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
+   laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+      VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, &laserPipeline.storageBufferSet.infoSet);
    laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &laserTextureImageDescriptor);
@@ -472,10 +480,12 @@
    explosionPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ExplosionVertex::objIndex));
 
-   createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_Explosion),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
 
    explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_explosionPipeline);
-   explosionPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
+   explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+      VK_SHADER_STAGE_VERTEX_BIT, &explosionPipeline.storageBufferSet.infoSet);
 
    explosionPipeline.createDescriptorSetLayout();
@@ -582,24 +592,54 @@
 
 void VulkanGame::initGraphicsPipelines() {
-   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(
+   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 24, 10);
 
-   shipPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(
+   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+      modelPipeline.storageBufferSet.buffers, modelPipeline.storageBufferSet.memory,
+      modelPipeline.storageBufferSet.infoSet);
+
+   shipPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 138, 138, 10);
 
-   asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_Asteroid>(
+   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+      shipPipeline.storageBufferSet.buffers, shipPipeline.storageBufferSet.memory,
+      shipPipeline.storageBufferSet.infoSet);
+
+   asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 36, 10);
 
-   laserPipeline = GraphicsPipeline_Vulkan<LaserVertex, SSBO_Laser>(
+   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Asteroid),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+      asteroidPipeline.storageBufferSet.buffers, asteroidPipeline.storageBufferSet.memory,
+      asteroidPipeline.storageBufferSet.infoSet);
+
+   laserPipeline = GraphicsPipeline_Vulkan<LaserVertex>(
       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 8, 18, 2);
 
-   explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion>(
+   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Laser),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+      laserPipeline.storageBufferSet.buffers, laserPipeline.storageBufferSet.memory,
+      laserPipeline.storageBufferSet.infoSet);
+
+   explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex>(
       VK_PRIMITIVE_TOPOLOGY_POINT_LIST, physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height },
       swapChainImages, EXPLOSION_PARTICLE_COUNT, EXPLOSION_PARTICLE_COUNT, 2);
+
+   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Explosion),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+      explosionPipeline.storageBufferSet.buffers, explosionPipeline.storageBufferSet.memory,
+      explosionPipeline.storageBufferSet.infoSet);
 }
 
@@ -1091,4 +1131,29 @@
    explosionPipeline.cleanupBuffers();
 
+   for (size_t i = 0; i < modelPipeline.storageBufferSet.buffers.size(); i++) {
+      vkDestroyBuffer(device, modelPipeline.storageBufferSet.buffers[i], nullptr);
+      vkFreeMemory(device, modelPipeline.storageBufferSet.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < shipPipeline.storageBufferSet.buffers.size(); i++) {
+      vkDestroyBuffer(device, shipPipeline.storageBufferSet.buffers[i], nullptr);
+      vkFreeMemory(device, shipPipeline.storageBufferSet.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < asteroidPipeline.storageBufferSet.buffers.size(); i++) {
+      vkDestroyBuffer(device, asteroidPipeline.storageBufferSet.buffers[i], nullptr);
+      vkFreeMemory(device, asteroidPipeline.storageBufferSet.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < laserPipeline.storageBufferSet.buffers.size(); i++) {
+      vkDestroyBuffer(device, laserPipeline.storageBufferSet.buffers[i], nullptr);
+      vkFreeMemory(device, laserPipeline.storageBufferSet.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < explosionPipeline.storageBufferSet.buffers.size(); i++) {
+      vkDestroyBuffer(device, explosionPipeline.storageBufferSet.buffers[i], nullptr);
+      vkFreeMemory(device, explosionPipeline.storageBufferSet.memory[i], nullptr);
+   }
+
    // END UNREVIEWED SECTION
 
@@ -1810,6 +1875,7 @@
 }
 
-void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
-   vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, vector<VkDescriptorBufferInfo>& bufferInfoList) {
+void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,
+                                 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
+                                 vector<VkDescriptorBufferInfo>& bufferInfoList) {
    buffers.resize(swapChainImageCount);
    buffersMemory.resize(swapChainImageCount);
@@ -1817,7 +1883,5 @@
 
    for (size_t i = 0; i < swapChainImageCount; i++) {
-      VulkanUtils::createBuffer(device, physicalDevice, bufferSize, flags,
-         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-         buffers[i], buffersMemory[i]);
+      VulkanUtils::createBuffer(device, physicalDevice, bufferSize, flags, properties, buffers[i], buffersMemory[i]);
 
       bufferInfoList[i].buffer = buffers[i];
@@ -2093,5 +2157,6 @@
    // instead of recreated every time
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
 
@@ -2101,5 +2166,6 @@
    modelPipeline.createDescriptorSets(swapChainImages);
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
 
@@ -2109,5 +2175,6 @@
    shipPipeline.createDescriptorSets(swapChainImages);
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
 
@@ -2117,5 +2184,6 @@
    asteroidPipeline.createDescriptorSets(swapChainImages);
 
-   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_VP_mats),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_laserPipeline, uniformBuffersMemory_laserPipeline, uniformBufferInfoList_laserPipeline);
 
@@ -2125,5 +2193,6 @@
    laserPipeline.createDescriptorSets(swapChainImages);
 
-   createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+   createBufferSet(sizeof(UBO_Explosion),
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
       uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
 
