diff --git a/Hello_triangle/main.cpp b/Hello_triangle/main.cpp index cc599b5..999d549 100644 --- a/Hello_triangle/main.cpp +++ b/Hello_triangle/main.cpp @@ -166,36 +166,90 @@ const std::vector deviceExtensions = { throw std::runtime_error("failed to find suitable memory type!"); } - void createVertexBuffer() { + + 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) { + if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) { throw std::runtime_error("failed to create vertex buffer!"); } VkMemoryRequirements memRequirements; - vkGetBufferMemoryRequirements(device, vertexBuffer, &memRequirements); + vkGetBufferMemoryRequirements(device, buffer, &memRequirements); VkMemoryAllocateInfo allocInfo{}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties); - if (vkAllocateMemory(device, &allocInfo, nullptr, &vertexBufferMemory)!= VK_SUCCESS) { + if (vkAllocateMemory(device, &allocInfo, nullptr, &buffermemory) != VK_SUCCESS) { throw std::runtime_error("failed to allocate vertex buffer memory!"); } - vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0); + vkBindBufferMemory(device, buffer, buffermemory, 0); + } + + + // copy from staging to the vertex buffer + 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; // Optional + copyRegion.dstOffset = 0; // Optional + copyRegion.size = size; + vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region); + + 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); + } + + // Create a staging and vertex buffer + 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, vertexBufferMemory, 0, bufferInfo.size, 0, &data); - memcpy(data, vertices.data(), (size_t)bufferInfo.size); - vkUnmapMemory(device, vertexBufferMemory); + 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); }