staging buffer

main
Benjamin Kraft 2 weeks ago
parent 3caf9e9a4e
commit 405411337c
  1. 13
      src/vulkan/application.cpp
  2. 3
      src/vulkan/application.hpp
  3. 72
      src/vulkan/buffer.cpp
  4. 13
      src/vulkan/buffer.hpp
  5. 2
      src/vulkan/command_pool.hpp

@ -1,5 +1,4 @@
#include "application.hpp" #include "application.hpp"
#include "vertex.hpp"
#include "swapchain.hpp" #include "swapchain.hpp"
#include "pipeline.hpp" #include "pipeline.hpp"
#include "instance.hpp" #include "instance.hpp"
@ -10,8 +9,13 @@ Application::Application() {
instance = new Instance; instance = new Instance;
swapchain = new Swapchain(instance); swapchain = new Swapchain(instance);
pipeline = new Pipeline(instance, swapchain->renderPass); pipeline = new Pipeline(instance, swapchain->renderPass);
buffer = new Buffer(instance); stagingBuffer = Buffer::createStagingBuffer(instance);
vertexBuffer = new Buffer(instance, stagingBuffer->size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
commandPool = new CommandPool(instance); commandPool = new CommandPool(instance);
stagingBuffer->copyTo(vertexBuffer, commandPool);
createSyncObjects(); createSyncObjects();
mainLoop(); mainLoop();
@ -129,7 +133,7 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im
scissor.extent = swapchain->extent; scissor.extent = swapchain->extent;
vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
VkBuffer buffers[] = {buffer->vertexHandle}; VkBuffer buffers[] = {vertexBuffer->handle};
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets); vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets);
@ -147,7 +151,8 @@ Application::~Application() {
vkDestroyFence(instance->device, inFlightFences[i], nullptr); vkDestroyFence(instance->device, inFlightFences[i], nullptr);
} }
delete commandPool; delete commandPool;
delete buffer; delete stagingBuffer;
delete vertexBuffer;
delete pipeline; delete pipeline;
delete instance; delete instance;
} }

@ -45,7 +45,8 @@ private:
Instance* instance = nullptr; Instance* instance = nullptr;
Swapchain* swapchain = nullptr; Swapchain* swapchain = nullptr;
Pipeline* pipeline = nullptr; Pipeline* pipeline = nullptr;
Buffer* buffer = nullptr; Buffer* stagingBuffer = nullptr;
Buffer* vertexBuffer = nullptr;
CommandPool* commandPool = nullptr; CommandPool* commandPool = nullptr;
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);

@ -3,6 +3,7 @@
#include "buffer.hpp" #include "buffer.hpp"
#include "vertex.hpp" #include "vertex.hpp"
#include "instance.hpp" #include "instance.hpp"
#include "command_pool.hpp"
const std::vector<Vertex> vertices = { const std::vector<Vertex> vertices = {
{{0.0, -0.5}, {1, 0, 0}}, {{0.0, -0.5}, {1, 0, 0}},
@ -10,31 +11,26 @@ const std::vector<Vertex> vertices = {
{{-0.5, 0.5}, {0, 0, 1}} {{-0.5, 0.5}, {0, 0, 1}}
}; };
Buffer::Buffer(Instance* instance) : instance(instance) { Buffer::Buffer(Instance* instance, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) : instance(instance), size(size){
VkBufferCreateInfo bufferInfo{}; VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = vertices.size() * sizeof(Vertex); bufferInfo.size = size;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vkCreateBuffer(instance->device, &bufferInfo, nullptr, &vertexHandle); vkCreateBuffer(instance->device, &bufferInfo, nullptr, &handle);
VkMemoryRequirements memoryRequirements; VkMemoryRequirements memoryRequirements;
vkGetBufferMemoryRequirements(instance->device, vertexHandle, &memoryRequirements); vkGetBufferMemoryRequirements(instance->device, handle, &memoryRequirements);
VkMemoryAllocateInfo allocateInfo {}; VkMemoryAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.allocationSize = memoryRequirements.size;
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, properties);
vkAllocateMemory(instance->device, &allocateInfo, nullptr, &vertexMemory); vkAllocateMemory(instance->device, &allocateInfo, nullptr, &memory);
vkBindBufferMemory(instance->device, vertexHandle, vertexMemory, 0); vkBindBufferMemory(instance->device, handle, memory, 0);
void* data;
vkMapMemory(instance->device, vertexMemory, 0, bufferInfo.size, 0, &data);
memcpy(data, vertices.data(), bufferInfo.size);
vkUnmapMemory(instance->device, vertexMemory);
} }
uint32_t Buffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags) { uint32_t Buffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags) {
@ -51,6 +47,52 @@ uint32_t Buffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags prope
} }
Buffer::~Buffer() { Buffer::~Buffer() {
vkFreeMemory(instance->device, vertexMemory, nullptr); vkFreeMemory(instance->device, memory, nullptr);
vkDestroyBuffer(instance->device, vertexHandle, nullptr); vkDestroyBuffer(instance->device, handle, nullptr);
}
Buffer* Buffer::createStagingBuffer(Instance* instance) {
VkDeviceSize size = vertices.size() * sizeof(Vertex);
VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
auto stagingBuffer = new Buffer(instance, size, usage, properties);
void* data;
vkMapMemory(instance->device, stagingBuffer->memory, 0, size, 0, &data);
memcpy(data, vertices.data(), size);
vkUnmapMemory(instance->device, stagingBuffer->memory);
return stagingBuffer;
}
void Buffer::copyTo(Buffer *dst, CommandPool* commandPool) {
VkCommandBufferAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandPool = commandPool->handle;
allocateInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(instance->device, &allocateInfo, &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.size = size;
vkCmdCopyBuffer(commandBuffer, handle, dst->handle, 1, &copyRegion);
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(instance->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkDeviceWaitIdle(instance->device);
vkFreeCommandBuffers(instance->device, commandPool->handle, 1, &commandBuffer);
} }

@ -4,17 +4,22 @@
#include <stdexcept> #include <stdexcept>
class Instance; class Instance;
class CommandPool;
class Buffer { class Buffer {
public: public:
explicit Buffer(Instance* instance); explicit Buffer(Instance* instance, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties);
~Buffer(); ~Buffer();
VkBuffer vertexHandle = VK_NULL_HANDLE; VkBuffer handle = VK_NULL_HANDLE;
VkDeviceMemory memory = VK_NULL_HANDLE;
VkDeviceSize size;
static Buffer* createStagingBuffer(Instance* instance);
void copyTo(Buffer* dst, CommandPool* commandPool);
private: private:
Instance* instance = nullptr; Instance* instance = nullptr;
VkDeviceMemory vertexMemory = VK_NULL_HANDLE;
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags); uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags);
}; };

@ -10,9 +10,9 @@ public:
explicit CommandPool(Instance* instance); explicit CommandPool(Instance* instance);
~CommandPool(); ~CommandPool();
std::vector<VkCommandBuffer> buffers; std::vector<VkCommandBuffer> buffers;
VkCommandPool handle = VK_NULL_HANDLE;
private: private:
Instance* instance; Instance* instance;
VkCommandPool handle = VK_NULL_HANDLE;
void createBuffers(); void createBuffers();
}; };
Loading…
Cancel
Save