From 56cc09ea221fa8ddf2fc17c0c7b4777c75155c12 Mon Sep 17 00:00:00 2001 From: Rick Rongen Date: Mon, 1 Jun 2020 20:49:36 +0200 Subject: [PATCH] feat: copy buffer --- src/HelloTriangleApplication.cpp | 78 +++++++++++++++++++++++++------- src/HelloTriangleApplication.h | 7 +++ src/MyVkInstance.cpp | 3 +- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/src/HelloTriangleApplication.cpp b/src/HelloTriangleApplication.cpp index 486ea25..2508e3c 100644 --- a/src/HelloTriangleApplication.cpp +++ b/src/HelloTriangleApplication.cpp @@ -12,7 +12,6 @@ #define GLFW_INCLUDE_VULKAN #include -#include #include #include "queues.h" @@ -376,36 +375,83 @@ void HelloTriangleApplication::createFrameBuffers() { } } -void HelloTriangleApplication::createVertexBuffer() { +void HelloTriangleApplication::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) { VkBufferCreateInfo bufferCreateInfo { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .size = sizeof(vertices[0]) * vertices.size(), - .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .size = size, + .usage = usage, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, }; - if (vkCreateBuffer(myVkInstance->device, &bufferCreateInfo, nullptr, &vertexBuffer) != VK_SUCCESS) { + if (vkCreateBuffer(myVkInstance->device, &bufferCreateInfo, nullptr, &buffer) != VK_SUCCESS) { throw std::runtime_error("Failed to create vertex buffer"); } VkMemoryRequirements memoryRequirements; - vkGetBufferMemoryRequirements(myVkInstance->device, vertexBuffer, &memoryRequirements); + vkGetBufferMemoryRequirements(myVkInstance->device, buffer, &memoryRequirements); VkMemoryAllocateInfo allocateInfo{ - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .allocationSize = memoryRequirements.size, - .memoryTypeIndex = myVkInstance->findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = memoryRequirements.size, + .memoryTypeIndex = myVkInstance->findMemoryType(memoryRequirements.memoryTypeBits, properties), }; - if (vkAllocateMemory(myVkInstance->device, &allocateInfo, nullptr, &vertexBufferMemory) != VK_SUCCESS) { + if (vkAllocateMemory(myVkInstance->device, &allocateInfo, nullptr, &bufferMemory) != VK_SUCCESS) { throw std::runtime_error("Failed to allocate vertex buffer memory"); } - vkBindBufferMemory(myVkInstance->device, vertexBuffer, vertexBufferMemory, 0); + vkBindBufferMemory(myVkInstance->device, buffer, bufferMemory, 0); +} + +void HelloTriangleApplication::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(myVkInstance->device, vertexBufferMemory, 0, bufferCreateInfo.size, 0, &data); - memcpy(data, vertices.data(), (size_t)bufferCreateInfo.size); - vkUnmapMemory(myVkInstance->device, vertexBufferMemory); + vkMapMemory(myVkInstance->device, stagingBufferMemory, 0, bufferSize, 0, &data); + memcpy(data, vertices.data(), (size_t)bufferSize); + vkUnmapMemory(myVkInstance->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(myVkInstance->device, stagingBuffer, nullptr); + vkFreeMemory(myVkInstance->device, stagingBufferMemory, nullptr); +} + +void HelloTriangleApplication::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) { + VkCommandBufferAllocateInfo commandBufferAllocateInfo{ + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .commandPool = commandPool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + VkCommandBuffer commandBuffer; + vkAllocateCommandBuffers(myVkInstance->device, &commandBufferAllocateInfo, &commandBuffer); + VkCommandBufferBeginInfo beginInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + }; + vkBeginCommandBuffer(commandBuffer, &beginInfo); + VkBufferCopy copyRegion { + .srcOffset = 0, + .dstOffset = 0, + .size = size + }; + vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region); + vkEndCommandBuffer(commandBuffer); + VkSubmitInfo submitInfo { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .commandBufferCount = 1, + .pCommandBuffers = &commandBuffer, + }; + vkQueueSubmit(myVkInstance->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); + vkQueueWaitIdle(myVkInstance->graphicsQueue); + vkFreeCommandBuffers(myVkInstance->device, commandPool, 1, &commandBuffer); } void HelloTriangleApplication::createCommandPool() { diff --git a/src/HelloTriangleApplication.h b/src/HelloTriangleApplication.h index 1696be7..bd577e1 100644 --- a/src/HelloTriangleApplication.h +++ b/src/HelloTriangleApplication.h @@ -68,6 +68,13 @@ private: VkShaderModule createShaderModule(const std::vector &code); static void frameBufferResizeCallback(void *thisptr, int width, int height); + + void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, + VkDeviceMemory &deviceMemory); + + void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); + + }; diff --git a/src/MyVkInstance.cpp b/src/MyVkInstance.cpp index 69bdced..ee8e0db 100644 --- a/src/MyVkInstance.cpp +++ b/src/MyVkInstance.cpp @@ -6,7 +6,6 @@ #include "debugLayers.h" #include "queues.h" -#include #include #include @@ -77,6 +76,8 @@ void MyVkInstance::initWindow() { glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); window = glfwCreateWindow(this->width, this->height, this->title.c_str(), nullptr, nullptr); + glfwSetWindowUserPointer(window, this); + glfwSetFramebufferSizeCallback(window, MyVkInstance::frameBufferResizeCallbackHandler); }