1 #include <msp/core/algorithm.h>
3 #include "transferqueue.h"
11 TransferQueue::TransferQueue(Device &d):
15 TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(void *object, bool ordered, size_t size)
17 unsigned &order = next_orders[object];
19 order += (order&1)|ordered;
21 auto j = upper_bound_member(transfers, order, &PendingTransfer::order);
23 PendingTransfer &transfer = *transfers.emplace(j);
24 transfer.order = order;
28 auto i = find_if(buffers, [size](const StagingBuffer &b){ return b.used+size<=b.size; });
31 buffers.emplace_back(device, max(default_buffer_size, size));
32 i = prev(buffers.end());
35 transfer.buffer_index = distance(buffers.begin(), i);
36 transfer.offset = i->used;
47 void TransferQueue::dispatch_transfers(VkCommandBuffer command_buffer)
52 for(auto i=transfers.begin(); i!=transfers.end(); )
55 for(; (j!=transfers.end() && j->order==i->order); ++j)
58 device.get_synchronizer().barrier(command_buffer);
62 VkBuffer buffer = (i->buffer_index>=0 ? buffers[i->buffer_index].buffer : 0);
63 i->transfer(command_buffer, buffer, i->offset);
72 TransferQueue::StagingBuffer::StagingBuffer(Device &d, size_t s):
76 const VulkanFunctions &vk = device.get_functions();
78 VkBufferCreateInfo buffer_info = { };
79 buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
80 buffer_info.size = size;
81 buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
82 buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
84 vk.CreateBuffer(buffer_info, buffer);
86 MemoryAllocator &allocator = device.get_allocator();
87 memory_id = allocator.allocate(buffer, STAGING_MEMORY);
88 mapped_address = allocator.map(memory_id, 0, size);
91 TransferQueue::StagingBuffer::StagingBuffer(StagingBuffer &&other):
94 memory_id(other.memory_id),
97 mapped_address(other.mapped_address)
101 other.mapped_address = 0;
104 TransferQueue::StagingBuffer::~StagingBuffer()
106 const VulkanFunctions &vk = device.get_functions();
107 MemoryAllocator &allocator = device.get_allocator();
111 allocator.unmap(mapped_address);
112 allocator.release(memory_id);
115 vk.DestroyBuffer(buffer);