--- /dev/null
+#ifndef MSP_GL_VULKAN_TRANSFERQUEUE_H_
+#define MSP_GL_VULKAN_TRANSFERQUEUE_H_
+
+#include <functional>
+#include <vector>
+#include "handles.h"
+
+namespace Msp {
+namespace GL {
+
+class Buffer;
+class Device;
+
+class TransferQueue
+{
+private:
+ struct StagingBuffer
+ {
+ Device &device;
+ VkBuffer buffer = 0;
+ unsigned memory_id = 0;
+ std::size_t size = 0;
+ std::size_t used = 0;
+ void *mapped_address = 0;
+
+ StagingBuffer(Device &, std::size_t);
+ StagingBuffer(StagingBuffer &&);
+ ~StagingBuffer();
+ };
+
+ using TransferCallback = void(VkCommandBuffer, VkBuffer, std::size_t);
+
+ struct PendingTransfer
+ {
+ unsigned buffer_index = 0;
+ std::size_t offset = 0;
+ std::size_t size = 0;
+ std::function<TransferCallback> callback;
+ };
+
+ Device &device;
+ std::size_t default_buffer_size = 16*1048576;
+ std::vector<StagingBuffer> buffers;
+ std::vector<PendingTransfer> transfers;
+
+public:
+ TransferQueue(Device &);
+
+ template<typename T>
+ void *prepare_transfer(std::size_t, T &&);
+
+private:
+ PendingTransfer &prepare_transfer(std::size_t);
+
+public:
+ void dispatch_transfers(VkCommandBuffer);
+};
+
+template<typename T>
+void *TransferQueue::prepare_transfer(std::size_t size, T &&callback)
+{
+ PendingTransfer &pt = prepare_transfer(size);
+ pt.callback = std::forward<T>(callback);
+ return static_cast<char *>(buffers[pt.buffer_index].mapped_address)+pt.offset;
+}
+
+} // namespace GL
+} // namespace Msp
+
+#endif