Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 80edd70437ab00d07490dffe468e1b971f7bc630)
+++ vulkan-game.cpp	(revision d9ef6abf8f84c3924d1d1742f0dd473aac90c71f)
@@ -857,32 +857,87 @@
 
       void createVertexBuffer() {
+         VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
+
+         VkBuffer stagingBuffer;
+         VkDeviceMemory stagingBufferMemory;
+         createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 
+            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+            stagingBuffer, stagingBufferMemory);
+
+         void* data;
+         vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
+         memcpy(data, vertices.data(), (size_t)bufferSize);
+         vkUnmapMemory(device, stagingBufferMemory);
+
+         createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
+
+         copyBuffer(stagingBuffer, vertexBuffer, bufferSize);
+
+         vkDestroyBuffer(device, stagingBuffer, nullptr);
+         vkFreeMemory(device, stagingBufferMemory, nullptr);
+      }
+
+      void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties,
+            VkBuffer& buffer, VkDeviceMemory& bufferMemory) {
          VkBufferCreateInfo bufferInfo = {};
          bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-         bufferInfo.size = sizeof(vertices[0]) * vertices.size();
-         bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+         bufferInfo.size = size;
+         bufferInfo.usage = usage;
          bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
 
-         if (vkCreateBuffer(device, &bufferInfo, nullptr, &vertexBuffer) != VK_SUCCESS) {
-            throw runtime_error("failed to create vertex buffer!");
-         }
-
-         VkMemoryRequirements memoryRequirements;
-         vkGetBufferMemoryRequirements(device, vertexBuffer, &memoryRequirements);
+         if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
+            throw runtime_error("failed to create buffer!");
+         }
+
+         VkMemoryRequirements memRequirements;
+         vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
 
          VkMemoryAllocateInfo allocInfo = {};
          allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-         allocInfo.allocationSize = memoryRequirements.size;
-         allocInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-
-         if (vkAllocateMemory(device, &allocInfo, nullptr, &vertexBufferMemory) != VK_SUCCESS) {
-            throw runtime_error("failed to allocate vertex buffer memory!");
-         }
-
-         vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0);
-
-         void* data;
-         vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, &data);
-         memcpy(data, vertices.data(), (size_t)bufferInfo.size);
-         vkUnmapMemory(device, vertexBufferMemory);
+         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!");
+         }
+
+         vkBindBufferMemory(device, buffer, bufferMemory, 0);
+      }
+
+      void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
+         VkCommandBufferAllocateInfo allocInfo = {};
+         allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+         allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+         allocInfo.commandPool = commandPool;
+         allocInfo.commandBufferCount = 1;
+
+         VkCommandBuffer commandBuffer;
+         vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
+
+         VkCommandBufferBeginInfo beginInfo = {};
+         beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+         beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+
+         vkBeginCommandBuffer(commandBuffer, &beginInfo);
+
+         VkBufferCopy copyRegion = {};
+         copyRegion.srcOffset = 0;
+         copyRegion.dstOffset = 0;
+         copyRegion.size = size;
+   
+         vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
+
+         vkEndCommandBuffer(commandBuffer);
+
+         VkSubmitInfo submitInfo = {};
+         submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+         submitInfo.commandBufferCount = 1;
+         submitInfo.pCommandBuffers = &commandBuffer;
+
+         vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
+         vkQueueWaitIdle(graphicsQueue);
+
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
       }
 
