+ ++i->async_count;
+}
+
+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);
+
+ if(i->buffer_index>=0)
+ --buffers[i->buffer_index].async_count;
+ 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;