VkBufferCreateInfo buffer_info = { };
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- buffer_info.size = self.size;
+ buffer_info.size = self.get_total_size();
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT|VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
void VulkanBuffer::sub_data(size_t off, size_t sz, const void *d)
{
- device.get_synchronizer().write_buffer(handle, off, sz);
-
- void *staging = device.get_transfer_queue().prepare_transfer(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, ®ion);
- });
-
+ 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));
+ copy(src, src+sz, static_cast<char *>(transfer.get_address()));
+}
+
+unsigned VulkanBuffer::get_multiplicity() const
+{
+ BufferUsage usage = static_cast<const Buffer *>(this)->usage;
+ return (usage==STREAMING ? device.get_n_frames_in_flight() : 1);
}
bool VulkanBuffer::can_map() const
void *VulkanBuffer::map()
{
- size_t size = static_cast<const Buffer *>(this)->size;
- mapped_address = device.get_allocator().map(memory_id, 0, size);
+ mapped_address = device.get_allocator().map(memory_id);
return mapped_address;
}
bool VulkanBuffer::unmap()
{
- device.get_allocator().unmap(mapped_address);
+ device.get_allocator().unmap(memory_id);
mapped_address = 0;
return true;
}
#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 = buf.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](const VulkanCommandRecorder &vkCmd, VkBuffer staging_buf, size_t src_off){
+ VkBufferCopy region = { };
+ region.srcOffset = src_off;
+ region.dstOffset = off;
+ region.size = sz;
+ vkCmd.CopyBuffer(staging_buf, buf.handle, 1, ®ion);
+ });
+ }
+}
+
+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