X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Ftransferqueue.cpp;h=87afc3c0b516fcefc0ec395fb93e1a4fa63dd3a8;hb=682d3ceda19df700ce6590028717e4f0042783ec;hp=8080f673226db30bf0aca97c35a0aec61b7d9570;hpb=99ca354f18119f82f1adeca100cd665a8f640317;p=libs%2Fgl.git diff --git a/source/backends/vulkan/transferqueue.cpp b/source/backends/vulkan/transferqueue.cpp index 8080f673..87afc3c0 100644 --- a/source/backends/vulkan/transferqueue.cpp +++ b/source/backends/vulkan/transferqueue.cpp @@ -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,26 +30,39 @@ 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) { - for(const PendingTransfer &t: transfers) + if(transfers.empty()) + return; + + for(auto i=transfers.begin(); i!=transfers.end(); ) { - VkBuffer buffer = buffers[t.buffer_index].buffer; - t.callback(command_buffer, buffer, t.offset); + auto j = i; + for(; (j!=transfers.end() && j->order==i->order); ++j) + j->synchronize(); + + device.get_synchronizer().barrier(command_buffer); + + for(; i!=j; ++i) + { + VkBuffer buffer = buffers[i->buffer_index].buffer; + i->transfer(command_buffer, buffer, i->offset); + } } transfers.clear(); + next_orders.clear(); }