]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/buffer_backend.cpp
Redesign asynchronous buffer uploads
[libs/gl.git] / source / backends / vulkan / buffer_backend.cpp
index 5439548f886fd1d81ba0ac16181f12c4a213f28f..aaf415703db8158e5cba7cacd4b6d93ee294f769 100644 (file)
@@ -52,24 +52,9 @@ void VulkanBuffer::allocate()
 
 void VulkanBuffer::sub_data(size_t off, size_t sz, const void *d)
 {
-       TransferQueue &tq = device.get_transfer_queue();
-       void *staging = tq.prepare_transfer(this, false, sz,
-               [this, off, sz](){
-                       device.get_synchronizer().write_buffer(handle, off, sz);
-               },
-               [this, off, sz](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
-                       const VulkanFunctions &vk = device.get_functions();
-
-                       VkBufferCopy region = { };
-                       region.srcOffset = src_off;
-                       region.dstOffset = off;
-                       region.size = sz;
-                       vk.CmdCopyBuffer(cmd_buf, staging_buf, handle, 1, &region);
-               });
-
+       Buffer::AsyncTransfer transfer(*static_cast<Buffer *>(this), off, sz);
        const char *src = static_cast<const char *>(d);
-       copy(src, src+sz, static_cast<char *>(staging));
-       tq.finalize_transfer(staging);
+       copy(src, src+sz, static_cast<char *>(transfer.get_address()));
 }
 
 unsigned VulkanBuffer::get_multiplicity() const
@@ -122,5 +107,43 @@ void VulkanBuffer::set_vulkan_object_name() const
 #endif
 }
 
+
+void Buffer::AsyncTransfer::allocate()
+{
+       if(buffer.can_map())
+               dest_addr = static_cast<char *>(buffer.map())+offset;
+       else
+       {
+               Buffer &buf = buffer;
+               size_t off = offset;
+               size_t sz = size;
+
+               dest_addr = buffer.device.get_transfer_queue().prepare_transfer(&buffer, false, size,
+                       [&buf, off, sz](){
+                               buf.device.get_synchronizer().write_buffer(buf.handle, off, sz);
+                       },
+                       [&buf, off, sz](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
+                               const VulkanFunctions &vk = buf.device.get_functions();
+
+                               VkBufferCopy region = { };
+                               region.srcOffset = src_off;
+                               region.dstOffset = off;
+                               region.size = sz;
+                               vk.CmdCopyBuffer(cmd_buf, staging_buf, buf.handle, 1, &region);
+                       });
+       }
+}
+
+void Buffer::AsyncTransfer::finalize()
+{
+       if(buffer.can_map())
+       {
+               buffer.unmap();
+               buffer.device.get_synchronizer().write_buffer(buffer.handle, offset, size, true);
+       }
+       else
+               buffer.device.get_transfer_queue().finalize_transfer(dest_addr);
+}
+
 } // namespace GL
 } // namespace Msp