]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/transferqueue.cpp
Track the order of transfers involving the same objects
[libs/gl.git] / source / backends / vulkan / transferqueue.cpp
index 7f1cfa914884a518a7c766abe385204f72766e66..87afc3c0b516fcefc0ec395fb93e1a4fa63dd3a8 100644 (file)
@@ -12,8 +12,17 @@ TransferQueue::TransferQueue(Device &d):
        device(d)
 { }
 
-TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(size_t size)
+TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(void *object, bool ordered, size_t size)
 {
+       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;
+
        auto i = find_if(buffers, [size](const StagingBuffer &b){ return b.used+size<=b.size; });
        if(i==buffers.end())
        {
@@ -21,15 +30,15 @@ TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(size_t size)
                i = prev(buffers.end());
        }
 
-       PendingTransfer transfer;
        transfer.buffer_index = distance(buffers.begin(), i);
        transfer.offset = i->used;
        transfer.size = size;
-       transfers.push_back(transfer);
 
        i->used += size;
 
-       return transfers.back();
+       order += ordered;
+
+       return transfer;
 }
 
 void TransferQueue::dispatch_transfers(VkCommandBuffer command_buffer)
@@ -37,18 +46,23 @@ 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 = buffers[i->buffer_index].buffer;
+                       i->transfer(command_buffer, buffer, i->offset);
+               }
        }
 
        transfers.clear();
+       next_orders.clear();
 }