device(d)
{ }
-TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(size_t size)
+TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(const void *object, bool ordered, size_t size)
{
- auto i = find_if(buffers, [size](const StagingBuffer &b){ return b.used+size<=b.size; });
- if(i==buffers.end())
+ unsigned &order = next_orders[object];
+ order += !order;
+ order += (order&1)|ordered;
+
+ auto j = upper_bound_member(transfers, order, &PendingTransfer::order);
+
+ PendingTransfer &transfer = *transfers.emplace(j);
+ transfer.order = order;
+
+ if(size)
{
- buffers.emplace_back(device, max(default_buffer_size, size));
- i = prev(buffers.end());
+ auto i = find_if(buffers, [size](const StagingBuffer &b){ return b.used+size<=b.size; });
+ if(i==buffers.end())
+ {
+ buffers.emplace_back(device, max(default_buffer_size, size));
+ i = prev(buffers.end());
+ }
+
+ transfer.buffer_index = distance(buffers.begin(), i);
+ transfer.offset = i->used;
+ transfer.size = size;
+
+ i->used += size;
}
- PendingTransfer transfer;
- transfer.buffer_index = distance(buffers.begin(), i);
- transfer.offset = i->used;
- transfer.size = size;
- transfers.push_back(transfer);
+ order += ordered;
- i->used += size;
-
- return transfers.back();
+ return transfer;
}
void TransferQueue::dispatch_transfers(VkCommandBuffer command_buffer)
if(transfers.empty())
return;
- for(const PendingTransfer &t: transfers)
- t.synchronize();
+ for(auto i=transfers.begin(); i!=transfers.end(); )
+ {
+ auto j = i;
+ for(; (j!=transfers.end() && j->order==i->order); ++j)
+ j->synchronize();
- device.get_synchronizer().barrier(command_buffer);
+ device.get_synchronizer().barrier(command_buffer);
- for(const PendingTransfer &t: transfers)
- {
- VkBuffer buffer = buffers[t.buffer_index].buffer;
- t.transfer(command_buffer, buffer, t.offset);
+ for(; i!=j; ++i)
+ {
+ VkBuffer buffer = (i->buffer_index>=0 ? buffers[i->buffer_index].buffer : 0);
+ i->transfer(command_buffer, buffer, i->offset);
+ }
}
transfers.clear();
+ next_orders.clear();
}