X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Ftransferqueue.cpp;h=8db81020425ee5e705b15bee3e098002483cf728;hb=33253bf6d6a330181fda83ba23a6ac0a756d9a8d;hp=87afc3c0b516fcefc0ec395fb93e1a4fa63dd3a8;hpb=682d3ceda19df700ce6590028717e4f0042783ec;p=libs%2Fgl.git diff --git a/source/backends/vulkan/transferqueue.cpp b/source/backends/vulkan/transferqueue.cpp index 87afc3c0..8db81020 100644 --- a/source/backends/vulkan/transferqueue.cpp +++ b/source/backends/vulkan/transferqueue.cpp @@ -1,4 +1,5 @@ #include +#include #include "device.h" #include "transferqueue.h" #include "vulkan.h" @@ -12,17 +13,8 @@ TransferQueue::TransferQueue(Device &d): device(d) { } -TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(void *object, bool ordered, size_t size) +void TransferQueue::allocate_staging(PendingTransfer &transfer, 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()) { @@ -33,12 +25,53 @@ TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(void *object, bo transfer.buffer_index = distance(buffers.begin(), i); transfer.offset = i->used; transfer.size = size; + transfer.staging_address = static_cast(i->mapped_address)+transfer.offset; i->used += size; +} + +TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(const void *object, bool ordered, size_t size) +{ + PendingTransfer transfer; + transfer.object = object; + transfer.order = ordered; + + if(size) + { + allocate_staging(transfer, size); + auto i = lower_bound_member(async_transfers, transfer.staging_address, &PendingTransfer::staging_address); + i = async_transfers.emplace(i, move(transfer)); + return *i; + } + else + return insert_transfer(move(transfer)); +} + +void TransferQueue::finalize_transfer(void *staging) +{ + auto i = lower_bound_member(async_transfers, staging, &PendingTransfer::staging_address); + if(i==async_transfers.end() || i->staging_address!=staging) + throw key_error(staging); + + insert_transfer(move(*i)); + async_transfers.erase(i); +} + +TransferQueue::PendingTransfer &TransferQueue::insert_transfer(PendingTransfer &&pt) +{ + bool ordered = pt.order; + + unsigned &order = next_orders[pt.object]; + order += !order; + order += (order&1)|ordered; + + auto j = upper_bound_member(transfers, order, &PendingTransfer::order); + j = transfers.emplace(j, move(pt)); + j->order = order; order += ordered; - return transfer; + return *j; } void TransferQueue::dispatch_transfers(VkCommandBuffer command_buffer) @@ -56,7 +89,7 @@ void TransferQueue::dispatch_transfers(VkCommandBuffer command_buffer) for(; i!=j; ++i) { - VkBuffer buffer = buffers[i->buffer_index].buffer; + VkBuffer buffer = (i->buffer_index>=0 ? buffers[i->buffer_index].buffer : 0); i->transfer(command_buffer, buffer, i->offset); } }