X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Ftransferqueue.cpp;h=8db81020425ee5e705b15bee3e098002483cf728;hb=33253bf6d6a330181fda83ba23a6ac0a756d9a8d;hp=8040f245f5360a33ae31fb6a23b34cd392c8dbf9;hpb=5c35768c310847df816d216eecf8fa2e93f5f8b8;p=libs%2Fgl.git diff --git a/source/backends/vulkan/transferqueue.cpp b/source/backends/vulkan/transferqueue.cpp index 8040f245..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,36 +13,65 @@ 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 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()); + } - auto j = upper_bound_member(transfers, order, &PendingTransfer::order); + transfer.buffer_index = distance(buffers.begin(), i); + transfer.offset = i->used; + transfer.size = size; + transfer.staging_address = static_cast(i->mapped_address)+transfer.offset; - PendingTransfer &transfer = *transfers.emplace(j); - transfer.order = order; + 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) { - 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()); - } + 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)); +} - transfer.buffer_index = distance(buffers.begin(), i); - transfer.offset = i->used; - transfer.size = size; +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); - i->used += size; - } + 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)