From 1350d6adf7c7925834cecd34cc30388dc928141e Mon Sep 17 00:00:00 2001 From: Rebekah Rowe Date: Mon, 15 Jul 2024 06:59:47 -0400 Subject: [PATCH] Implimented a Vertex Staging buffer to make startup and buffer-copies faster. --- src/main.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 02fb44e..8067e78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -111,6 +111,8 @@ class VulkanExampleApplication { std::unique_ptr vk_buffer_vertex_memory; // in order to get a clean desctruction sequence, instantiate the DeviceMemory for the vertex buffer first std::unique_ptr vk_buffer_vertex; // https://github.com/KhronosGroup/Vulkan-Hpp/blob/6f72ceca515d59f40d64b64cf2734f6261e1f9f2/RAII_Samples/13_InitVertexBuffer/13_InitVertexBuffer.cpp + std::unique_ptr vk_buffer_vertex_staging_memory; // optional, but speeds things up! + std::unique_ptr vk_buffer_vertex_staging; struct Vertex { glm::vec2 pos; @@ -645,11 +647,14 @@ public: } { const auto vertex_buffer_size = sizeof(triangle_vertices[0]) * triangle_vertices.size(); - std::tie(this->vk_buffer_vertex, this->vk_buffer_vertex_memory) = CreateBuffer(vertex_buffer_size, vk::BufferUsageFlagBits::eVertexBuffer, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); + std::tie(this->vk_buffer_vertex_staging, this->vk_buffer_vertex_staging_memory) = CreateBuffer(vertex_buffer_size, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); - std::uint8_t* const vertex_buffer_data = static_cast(this->vk_buffer_vertex_memory->mapMemory(0, vertex_buffer_size)); + std::uint8_t* const vertex_buffer_data = static_cast(this->vk_buffer_vertex_staging_memory->mapMemory(0, vertex_buffer_size)); memcpy(vertex_buffer_data, triangle_vertices.data(), vertex_buffer_size); - this->vk_buffer_vertex_memory->unmapMemory(); + this->vk_buffer_vertex_staging_memory->unmapMemory(); + + std::tie(this->vk_buffer_vertex, this->vk_buffer_vertex_memory) = CreateBuffer(vertex_buffer_size, vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eVertexBuffer, vk::MemoryPropertyFlagBits::eDeviceLocal); + this->CopyBuffer(*this->vk_buffer_vertex_staging, *this->vk_buffer_vertex, vertex_buffer_size); } { // syncronizing vars this->vk_semephore_image_available = std::make_unique(*this->vk_gpu, vk::SemaphoreCreateInfo {}); @@ -704,6 +709,30 @@ protected: allocated_buffer->bindMemory(**allocated_buffer_memory, 0); return { std::make_unique(std::move(*allocated_buffer)), std::make_unique(std::move(*allocated_buffer_memory)) }; }; + void CopyBuffer(const vk::Buffer& src_buffer, const vk::Buffer& dest_buffer, const vk::DeviceSize& size) const { + const vk::CommandBufferAllocateInfo command_buffer_allocate_info { + .commandPool = **this->vk_command_pool, + .level = vk::CommandBufferLevel::ePrimary, + .commandBufferCount = 1 + }; + const auto command_buffer = std::move(vk::raii::CommandBuffers(*this->vk_gpu, command_buffer_allocate_info).front()); + command_buffer.begin(vk::CommandBufferBeginInfo { .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit }); + + const vk::BufferCopy copy_region { + //.srcOffset = 0, // Optional + //.dstOffset = 0, // Optional + .size = size + }; + command_buffer.copyBuffer(src_buffer, dest_buffer, { copy_region }); + command_buffer.end(); + + const vk::SubmitInfo submit_queue { + .commandBufferCount = 1, + .pCommandBuffers = &*command_buffer, + }; + this->vk_queue_graphics->submit(submit_queue); + this->vk_queue_graphics->waitIdle(); + }; public: void Run() {