diff --git a/src/main.cpp b/src/main.cpp index 737acfb..1e1ad53 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -578,31 +578,87 @@ class VulkanApp { } fn createVertexBuffer() -> void { + vk::DeviceSize bufferSize = sizeof(mVertices[0]) * mVertices.size(); + + vk::UniqueBuffer stagingBuffer; + vk::UniqueDeviceMemory stagingBufferMemory; + + createBuffer( + bufferSize, + vk::BufferUsageFlagBits::eVertexBuffer, + vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, + stagingBuffer, + stagingBufferMemory + ); + + void* data = mDevice->mapMemory(stagingBufferMemory.get(), 0, bufferSize); + memcpy(data, mVertices.data(), static_cast(bufferSize)); + mDevice->unmapMemory(stagingBufferMemory.get()); + + createBuffer( + bufferSize, + vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst, + vk::MemoryPropertyFlagBits::eDeviceLocal, + mVertexBuffer, + mVertexBufferMemory + ); + + copyBuffer(stagingBuffer.get(), mVertexBuffer.get(), bufferSize); + + stagingBuffer.reset(); + stagingBufferMemory.reset(); + } + + fn createBuffer( + vk::DeviceSize deviceSize, + vk::BufferUsageFlags bufferUsageFlags, + vk::MemoryPropertyFlags memoryPropertyFlags, + vk::UniqueBuffer& buffer, + vk::UniqueDeviceMemory& bufferMemory + ) -> void { vk::BufferCreateInfo bufferInfo { - .size = sizeof(mVertices[0]) * mVertices.size(), - .usage = vk::BufferUsageFlagBits::eVertexBuffer, + .size = deviceSize, + .usage = bufferUsageFlags, .sharingMode = vk::SharingMode::eExclusive, }; - mVertexBuffer = mDevice->createBufferUnique(bufferInfo, nullptr); + buffer = mDevice->createBufferUnique(bufferInfo); - vk::MemoryRequirements memRequirements = mDevice->getBufferMemoryRequirements(mVertexBuffer.get()); + vk::MemoryRequirements memRequirements = mDevice->getBufferMemoryRequirements(buffer.get()); vk::MemoryAllocateInfo allocInfo { .allocationSize = memRequirements.size, - .memoryTypeIndex = findMemoryType( - memRequirements.memoryTypeBits, - vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent - ), + .memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, memoryPropertyFlags), }; - mVertexBufferMemory = mDevice->allocateMemoryUnique(allocInfo); + bufferMemory = mDevice->allocateMemoryUnique(allocInfo); - mDevice->bindBufferMemory(mVertexBuffer.get(), mVertexBufferMemory.get(), 0); + mDevice->bindBufferMemory(buffer.get(), bufferMemory.get(), 0); + } - void* data = mDevice->mapMemory(mVertexBufferMemory.get(), 0, bufferInfo.size); - memcpy(data, mVertices.data(), static_cast(bufferInfo.size)); - mDevice->unmapMemory(mVertexBufferMemory.get()); + fn copyBuffer(vk::Buffer srcBuffer, vk::Buffer dstBuffer, vk::DeviceSize deviceSize) -> void { + vk::CommandBufferAllocateInfo allocInfo { + .commandPool = mCommandPool.get(), + .level = vk::CommandBufferLevel::ePrimary, + .commandBufferCount = 1, + }; + + vk::UniqueCommandBuffer commandBuffer = std::move(mDevice->allocateCommandBuffersUnique(allocInfo)[0]); + + vk::CommandBufferBeginInfo beginInfo { .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit }; + + commandBuffer->begin(beginInfo); + + vk::BufferCopy copyRegion { .size = deviceSize }; + + commandBuffer->copyBuffer(srcBuffer, dstBuffer, 1, ©Region); + + commandBuffer->end(); + + vk::SubmitInfo submitInfo { .commandBufferCount = 1, .pCommandBuffers = &commandBuffer.get() }; + + mGraphicsQueue.submit(submitInfo, nullptr); + mGraphicsQueue.waitIdle(); } fn findMemoryType(u32 typeFilter, vk::MemoryPropertyFlags properties) -> u32 {