Index: graphics-pipeline_vulkan.hpp
===================================================================
--- graphics-pipeline_vulkan.hpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
+++ graphics-pipeline_vulkan.hpp	(revision 996dd3efcf576a5eaf4f04878167c007d853dbac)
@@ -22,13 +22,4 @@
 using namespace glm;
 
-// TODO: Use this struct for uniform buffers as well and rename it to VulkanBuffer (maybe move it to VulkanUtils)
-// Also, probably better to make this a vector of structs where each struct
-// has a VkBuffer, VkDeviceMemory, and VkDescriptorBufferInfo
-struct StorageBufferSet {
-   vector<VkBuffer> buffers;
-   vector<VkDeviceMemory> memory;
-   vector<VkDescriptorBufferInfo> infoSet;
-};
-
 // TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList
 struct DescriptorInfo {
@@ -45,7 +36,4 @@
    public:
       string vertShaderFile, fragShaderFile;
-
-      // TODO: Move this outside this classs, since it is no longer used here
-      StorageBufferSet storageBufferSet;
 
       // Both of these are only used for managing the SSBO, so move them out as well
Index: sdl-game.cpp
===================================================================
--- sdl-game.cpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
+++ sdl-game.cpp	(revision 996dd3efcf576a5eaf4f04878167c007d853dbac)
@@ -110,5 +110,5 @@
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &modelPipeline.storageBufferSet.infoSet);
+      VK_SHADER_STAGE_VERTEX_BIT, &storageBuffers_modelPipeline.infoSet);
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
@@ -131,5 +131,7 @@
       }, {
          mat4(1.0f)
-      }, false);
+      }, storageBuffers_modelPipeline, false);
+
+   updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);
 
    texturedSquare->model_base =
@@ -150,5 +152,7 @@
       }, {
          mat4(1.0f)
-      }, false);
+      }, storageBuffers_modelPipeline, false);
+
+   updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);
 
    texturedSquare->model_base =
@@ -264,6 +268,6 @@
       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);
+      storageBuffers_modelPipeline.buffers, storageBuffers_modelPipeline.memory,
+      storageBuffers_modelPipeline.infoSet);
 }
 
@@ -372,5 +376,7 @@
                         }, {
                            mat4(1.0f)
-                        }, true);
+                        }, storageBuffers_modelPipeline, true);
+
+                  updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare.ssbo);
 
                   texturedSquare.model_base =
@@ -439,8 +445,7 @@
 }
 
-// TODO: The only updates that need to happen once per Vulkan image are the SSBO ones,
-// which are already handled by updateObject(). Move this code to a different place,
-// where it will run just once per frame
 void VulkanGame::updateScene() {
+   // TODO: These two for loops could probably be combined into one
+
    for (SceneObject<ModelVertex, SSBO_ModelObject>& model : this->modelObjects) {
       model.model_transform =
@@ -450,7 +455,15 @@
    }
 
+   // TODO: Instead, update entire sections (up to 64k) of the dynamic ubo if some objects there have changed
+   // Also, update the objects modelMat and center in the loop above instead of here
    for (size_t i = 0; i < modelObjects.size(); i++) {
       if (modelObjects[i].modified) {
+         // TODO: Think about changing the SSBO-related code to also use a contiguous array
+         // to store the data on the cpu side instead of storing it per-object
+         // Then, I could also copy it to the GPU in one go
+         // Also, double-check if the alignment restrictions also hold for SSBOs
+
          updateObject(modelObjects, modelPipeline, i);
+         updateStorageBuffer(storageBuffers_modelPipeline, i, modelObjects[i].ssbo);
       }
    }
@@ -475,7 +488,7 @@
    modelPipeline.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 < storageBuffers_modelPipeline.buffers.size(); i++) {
+      vkDestroyBuffer(device, storageBuffers_modelPipeline.buffers[i], nullptr);
+      vkFreeMemory(device, storageBuffers_modelPipeline.memory[i], nullptr);
    }
 
Index: sdl-game.hpp
===================================================================
--- sdl-game.hpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
+++ sdl-game.hpp	(revision 996dd3efcf576a5eaf4f04878167c007d853dbac)
@@ -72,4 +72,13 @@
    alignas(16) mat4 view;
    alignas(16) mat4 proj;
+};
+
+// TODO: Use this struct for uniform buffers as well and probably combine it with the VulkanBuffer class
+// Also, probably better to make this a vector of structs where each struct
+// has a VkBuffer, VkDeviceMemory, and VkDescriptorBufferInfo
+struct StorageBufferSet {
+   vector<VkBuffer> buffers;
+   vector<VkDeviceMemory> memory;
+   vector<VkDescriptorBufferInfo> infoSet;
 };
 
@@ -208,4 +217,6 @@
       // wouldn't work since the whole pipeline couldn't have a common set of descriptors for the textures
       GraphicsPipeline_Vulkan<ModelVertex> modelPipeline;
+
+      StorageBufferSet storageBuffers_modelPipeline;
 
       // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo
@@ -297,5 +308,6 @@
                                                    GraphicsPipeline_Vulkan<VertexType>& pipeline,
                                                    const vector<VertexType>& vertices, vector<uint16_t> indices,
-                                                   SSBOType ssbo, bool pipelinesCreated);
+                                                   SSBOType ssbo, StorageBufferSet& storageBuffers,
+                                                   bool pipelinesCreated);
 
       template<class VertexType>
@@ -381,5 +393,6 @@
                                                          GraphicsPipeline_Vulkan<VertexType>& pipeline,
                                                          const vector<VertexType>& vertices, vector<uint16_t> indices,
-                                                         SSBOType ssbo, bool pipelinesCreated) {
+                                                         SSBOType ssbo, StorageBufferSet& storageBuffers,
+                                                         bool pipelinesCreated) {
    // TODO: Use the model field of ssbo to set the object's model_base
    // currently, the passed in model is useless since it gets overridden in updateObject() anyway
@@ -403,17 +416,18 @@
    pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue);
 
+   // TODO: Probably move the resizing to the VulkanBuffer class
+   // First, try moving this out of addObject
    bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity;
 
    if (resizeStorageBuffer) {
-      resizeStorageBufferSet<VertexType, SSBOType>(pipeline.storageBufferSet, resourceCommandPool, graphicsQueue, pipeline);
+      resizeStorageBufferSet<VertexType, SSBOType>(storageBuffers, resourceCommandPool, graphicsQueue, pipeline);
       pipeline.cleanup();
 
       // Assume the SSBO is always the 2nd binding
-      pipeline.updateDescriptorInfo(1, &pipeline.storageBufferSet.infoSet);
+      // TODO: Figure out a way to make this more flexible
+      pipeline.updateDescriptorInfo(1, &storageBuffers.infoSet);
    }
 
    pipeline.numObjects++;
-
-   updateStorageBuffer(pipeline.storageBufferSet, pipeline.numObjects - 1, obj.ssbo);
 
    // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated,
@@ -421,4 +435,5 @@
 
    if (pipelinesCreated) {
+      // TODO: See if I can avoid doing this when recreating the pipeline
       vkDeviceWaitIdle(device);
 
@@ -531,6 +546,4 @@
    obj.center = vec3(obj.ssbo.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
 
-   updateStorageBuffer(pipeline.storageBufferSet, index, obj.ssbo);
-
    obj.modified = false;
 }
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
+++ vulkan-game.cpp	(revision 996dd3efcf576a5eaf4f04878167c007d853dbac)
@@ -126,5 +126,5 @@
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &modelPipeline.storageBufferSet.infoSet);
+      VK_SHADER_STAGE_VERTEX_BIT, &storageBuffers_modelPipeline.infoSet);
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
@@ -145,5 +145,7 @@
          }, {
             mat4(1.0f)
-         }, false);
+         }, storageBuffers_modelPipeline, false);
+
+   updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);
 
    texturedSquare->model_base =
@@ -164,5 +166,7 @@
          }, {
             mat4(1.0f)
-         }, false);
+         }, storageBuffers_modelPipeline, false);
+
+   updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);
 
    texturedSquare->model_base =
@@ -189,5 +193,5 @@
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_shipPipeline);
    shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &shipPipeline.storageBufferSet.infoSet);
+      VK_SHADER_STAGE_VERTEX_BIT, &storageBuffers_shipPipeline.infoSet);
 
    // TODO: With the normals, indexing basically becomes pointless since no vertices will have exactly
@@ -424,5 +428,7 @@
       }, {
          mat4(1.0f)
-      }, false);
+      }, storageBuffers_shipPipeline, false);
+
+   updateStorageBuffer(storageBuffers_shipPipeline, shipPipeline.numObjects - 1, ship.ssbo);
 
    ship.model_base =
@@ -449,5 +455,5 @@
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_asteroidPipeline);
    asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &asteroidPipeline.storageBufferSet.infoSet);
+      VK_SHADER_STAGE_VERTEX_BIT, &storageBuffers_asteroidPipeline.infoSet);
 
    asteroidPipeline.createDescriptorSetLayout();
@@ -467,5 +473,5 @@
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_laserPipeline);
    laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, &laserPipeline.storageBufferSet.infoSet);
+      VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, &storageBuffers_laserPipeline.infoSet);
    laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &laserTextureImageDescriptor);
@@ -487,5 +493,5 @@
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_explosionPipeline);
    explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-      VK_SHADER_STAGE_VERTEX_BIT, &explosionPipeline.storageBufferSet.infoSet);
+      VK_SHADER_STAGE_VERTEX_BIT, &storageBuffers_explosionPipeline.infoSet);
 
    explosionPipeline.createDescriptorSetLayout();
@@ -599,6 +605,6 @@
       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);
+      storageBuffers_modelPipeline.buffers, storageBuffers_modelPipeline.memory,
+      storageBuffers_modelPipeline.infoSet);
 
    shipPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
@@ -609,6 +615,6 @@
       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);
+      storageBuffers_shipPipeline.buffers, storageBuffers_shipPipeline.memory,
+      storageBuffers_shipPipeline.infoSet);
 
    asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
@@ -619,6 +625,6 @@
       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);
+      storageBuffers_asteroidPipeline.buffers, storageBuffers_asteroidPipeline.memory,
+      storageBuffers_asteroidPipeline.infoSet);
 
    laserPipeline = GraphicsPipeline_Vulkan<LaserVertex>(
@@ -629,6 +635,6 @@
       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);
+      storageBuffers_laserPipeline.buffers, storageBuffers_laserPipeline.memory,
+      storageBuffers_laserPipeline.infoSet);
 
    explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex>(
@@ -640,6 +646,6 @@
       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);
+      storageBuffers_explosionPipeline.buffers, storageBuffers_explosionPipeline.memory,
+      storageBuffers_explosionPipeline.infoSet);
 }
 
@@ -762,5 +768,7 @@
                            }, {
                               mat4(1.0f)
-                           }, true);
+                           }, storageBuffers_modelPipeline, true);
+
+                  updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare.ssbo);
 
                   texturedSquare.model_base =
@@ -1042,5 +1050,7 @@
                   10.0f,
                   false
-               }, true);
+               }, storageBuffers_asteroidPipeline, true);
+
+      updateStorageBuffer(storageBuffers_asteroidPipeline, asteroidPipeline.numObjects - 1, asteroid.ssbo);
 
       // This accounts for the scaling in model_base.
@@ -1070,4 +1080,5 @@
       if (shipObjects[i].modified) {
          updateObject(shipObjects, shipPipeline, i);
+         updateStorageBuffer(storageBuffers_shipPipeline, i, shipObjects[i].ssbo);
       }
    }
@@ -1076,4 +1087,5 @@
       if (modelObjects[i].modified) {
          updateObject(modelObjects, modelPipeline, i);
+         updateStorageBuffer(storageBuffers_modelPipeline, i, modelObjects[i].ssbo);
       }
    }
@@ -1082,4 +1094,5 @@
       if (asteroidObjects[i].modified) {
          updateObject(asteroidObjects, asteroidPipeline, i);
+         updateStorageBuffer(storageBuffers_asteroidPipeline, i, asteroidObjects[i].ssbo);
       }
    }
@@ -1088,4 +1101,5 @@
       if (laserObjects[i].modified) {
          updateObject(laserObjects, laserPipeline, i);
+         updateStorageBuffer(storageBuffers_laserPipeline, i, laserObjects[i].ssbo);
       }
    }
@@ -1094,4 +1108,5 @@
       if (explosionObjects[i].modified) {
          updateObject(explosionObjects, explosionPipeline, i);
+         updateStorageBuffer(storageBuffers_explosionPipeline, i, explosionObjects[i].ssbo);
       }
    }
@@ -1131,27 +1146,27 @@
    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);
+   for (size_t i = 0; i < storageBuffers_modelPipeline.buffers.size(); i++) {
+      vkDestroyBuffer(device, storageBuffers_modelPipeline.buffers[i], nullptr);
+      vkFreeMemory(device, storageBuffers_modelPipeline.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < storageBuffers_shipPipeline.buffers.size(); i++) {
+      vkDestroyBuffer(device, storageBuffers_shipPipeline.buffers[i], nullptr);
+      vkFreeMemory(device, storageBuffers_shipPipeline.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < storageBuffers_asteroidPipeline.buffers.size(); i++) {
+      vkDestroyBuffer(device, storageBuffers_asteroidPipeline.buffers[i], nullptr);
+      vkFreeMemory(device, storageBuffers_asteroidPipeline.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < storageBuffers_laserPipeline.buffers.size(); i++) {
+      vkDestroyBuffer(device, storageBuffers_laserPipeline.buffers[i], nullptr);
+      vkFreeMemory(device, storageBuffers_laserPipeline.memory[i], nullptr);
+   }
+
+   for (size_t i = 0; i < storageBuffers_explosionPipeline.buffers.size(); i++) {
+      vkDestroyBuffer(device, storageBuffers_explosionPipeline.buffers[i], nullptr);
+      vkFreeMemory(device, storageBuffers_explosionPipeline.memory[i], nullptr);
    }
 
@@ -1914,5 +1929,7 @@
          color,
          false
-      }, true);
+      }, storageBuffers_laserPipeline, true);
+
+   updateStorageBuffer(storageBuffers_laserPipeline, laserPipeline.numObjects - 1, laser.ssbo);
 
    float xAxisRotation = asin(ray.y / length);
@@ -2124,5 +2141,7 @@
          duration,
          false
-      }, true);
+      }, storageBuffers_explosionPipeline, true);
+
+   updateStorageBuffer(storageBuffers_explosionPipeline, explosionPipeline.numObjects - 1, explosion.ssbo);
 
    explosion.model_base = model_mat;
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
+++ vulkan-game.hpp	(revision 996dd3efcf576a5eaf4f04878167c007d853dbac)
@@ -96,4 +96,13 @@
    alignas(16) mat4 proj;
    alignas(4) float cur_time;
+};
+
+// TODO: Use this struct for uniform buffers as well and probably combine it with the VulkanBuffer class
+// Also, probably better to make this a vector of structs where each struct
+// has a VkBuffer, VkDeviceMemory, and VkDescriptorBufferInfo
+struct StorageBufferSet {
+   vector<VkBuffer> buffers;
+   vector<VkDeviceMemory> memory;
+   vector<VkDescriptorBufferInfo> infoSet;
 };
 
@@ -305,4 +314,10 @@
       GraphicsPipeline_Vulkan<LaserVertex> laserPipeline;
       GraphicsPipeline_Vulkan<ExplosionVertex> explosionPipeline;
+
+      StorageBufferSet storageBuffers_modelPipeline;
+      StorageBufferSet storageBuffers_shipPipeline;
+      StorageBufferSet storageBuffers_asteroidPipeline;
+      StorageBufferSet storageBuffers_laserPipeline;
+      StorageBufferSet storageBuffers_explosionPipeline;
 
       // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo
@@ -440,5 +455,6 @@
                                                    GraphicsPipeline_Vulkan<VertexType>& pipeline,
                                                    const vector<VertexType>& vertices, vector<uint16_t> indices,
-                                                   SSBOType ssbo, bool pipelinesCreated);
+                                                   SSBOType ssbo, StorageBufferSet& storageBuffers,
+                                                   bool pipelinesCreated);
 
       template<class VertexType>
@@ -544,5 +560,6 @@
                                                          GraphicsPipeline_Vulkan<VertexType>& pipeline,
                                                          const vector<VertexType>& vertices, vector<uint16_t> indices,
-                                                         SSBOType ssbo, bool pipelinesCreated) {
+                                                         SSBOType ssbo, StorageBufferSet& storageBuffers,
+                                                         bool pipelinesCreated) {
    // TODO: Use the model field of ssbo to set the object's model_base
    // currently, the passed in model is useless since it gets overridden in updateObject() anyway
@@ -566,17 +583,18 @@
    pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue);
 
+   // TODO: Probably move the resizing to the VulkanBuffer class
+   // First, try moving this out of addObject
    bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity;
 
    if (resizeStorageBuffer) {
-      resizeStorageBufferSet<VertexType, SSBOType>(pipeline.storageBufferSet, resourceCommandPool, graphicsQueue, pipeline);
+      resizeStorageBufferSet<VertexType, SSBOType>(storageBuffers, resourceCommandPool, graphicsQueue, pipeline);
       pipeline.cleanup();
 
       // Assume the SSBO is always the 2nd binding
-      pipeline.updateDescriptorInfo(1, &pipeline.storageBufferSet.infoSet);
+      // TODO: Figure out a way to make this more flexible
+      pipeline.updateDescriptorInfo(1, &storageBuffers.infoSet);
    }
 
    pipeline.numObjects++;
-
-   updateStorageBuffer(pipeline.storageBufferSet, pipeline.numObjects - 1, obj.ssbo);
 
    // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated,
@@ -584,4 +602,5 @@
 
    if (pipelinesCreated) {
+      // TODO: See if I can avoid doing this when recreating the pipeline
       vkDeviceWaitIdle(device);
 
@@ -699,6 +718,4 @@
    obj.center = vec3(obj.ssbo.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
 
-   updateStorageBuffer(pipeline.storageBufferSet, index, obj.ssbo);
-
    obj.modified = false;
 }
Index: vulkan-utils.hpp
===================================================================
--- vulkan-utils.hpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
+++ vulkan-utils.hpp	(revision 996dd3efcf576a5eaf4f04878167c007d853dbac)
@@ -117,5 +117,6 @@
 template<class DataType>
 void VulkanUtils::copyDataToBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool,
-      const vector<DataType>& srcData, VkBuffer dstBuffer, size_t dstVertexOffset, VkQueue graphicsQueue) {
+                                   const vector<DataType>& srcData, VkBuffer dstBuffer, size_t dstVertexOffset,
+                                   VkQueue graphicsQueue) {
    VkDeviceSize srcDataSize = srcData.size() * sizeof(DataType);
 
@@ -140,8 +141,10 @@
 template<class DataType>
 void VulkanUtils::copyDataToMemory(VkDevice device, const DataType& srcData, VkDeviceMemory bufferMemory,
-   VkDeviceSize offset) {
+                                   VkDeviceSize offset) {
    copyDataToMemory(device, srcData, bufferMemory, offset, sizeof(DataType));
 }
 
+// TODO: This would be used when the GPU memory is host-coherent. If it it not, I also need to use vkFlushMappedMemoryRanges
+// I should create a variant that supports non-coherent memory
 template<class DataType>
 void VulkanUtils::copyDataToMemory(VkDevice device, const DataType& srcData, VkDeviceMemory bufferMemory,
