1 #include <msp/core/algorithm.h>
3 #include "transferqueue.h"
11 TransferQueue::TransferQueue(Device &d):
15 TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(size_t size)
17 auto i = find_if(buffers, [size](const StagingBuffer &b){ return b.used+size<=b.size; });
20 buffers.emplace_back(device, max(default_buffer_size, size));
21 i = prev(buffers.end());
24 PendingTransfer transfer;
25 transfer.buffer_index = distance(buffers.begin(), i);
26 transfer.offset = i->used;
28 transfers.push_back(transfer);
32 return transfers.back();
35 void TransferQueue::dispatch_transfers(VkCommandBuffer command_buffer)
40 for(const PendingTransfer &t: transfers)
43 device.get_synchronizer().barrier(command_buffer);
45 for(const PendingTransfer &t: transfers)
47 VkBuffer buffer = buffers[t.buffer_index].buffer;
48 t.transfer(command_buffer, buffer, t.offset);
55 TransferQueue::StagingBuffer::StagingBuffer(Device &d, size_t s):
59 const VulkanFunctions &vk = device.get_functions();
61 VkBufferCreateInfo buffer_info = { };
62 buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
63 buffer_info.size = size;
64 buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
65 buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
67 vk.CreateBuffer(buffer_info, buffer);
69 MemoryAllocator &allocator = device.get_allocator();
70 memory_id = allocator.allocate(buffer, STAGING_MEMORY);
71 mapped_address = allocator.map(memory_id, 0, size);
74 TransferQueue::StagingBuffer::StagingBuffer(StagingBuffer &&other):
77 memory_id(other.memory_id),
80 mapped_address(other.mapped_address)
84 other.mapped_address = 0;
87 TransferQueue::StagingBuffer::~StagingBuffer()
89 const VulkanFunctions &vk = device.get_functions();
90 MemoryAllocator &allocator = device.get_allocator();
94 allocator.unmap(mapped_address);
95 allocator.release(memory_id);
98 vk.DestroyBuffer(buffer);