2 #include "buffer_backend.h"
11 VulkanBuffer::VulkanBuffer():
12 device(Device::get_current())
15 VulkanBuffer::VulkanBuffer(VulkanBuffer &&other):
18 memory_id(other.memory_id),
19 mapped_address(other.mapped_address),
20 debug_name(move(other.debug_name))
24 other.mapped_address = 0;
27 VulkanBuffer::~VulkanBuffer()
30 device.get_destroy_queue().destroy(handle, memory_id);
33 void VulkanBuffer::allocate()
35 const Buffer &self = *static_cast<const Buffer *>(this);
36 const VulkanFunctions &vk = device.get_functions();
38 VkBufferCreateInfo buffer_info = { };
39 buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
40 buffer_info.size = self.get_total_size();
41 buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT|
42 VK_BUFFER_USAGE_INDEX_BUFFER_BIT|VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
43 buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
45 vk.CreateBuffer(buffer_info, handle);
47 memory_id = device.get_allocator().allocate(handle, (self.usage==STREAMING ? STREAMING_MEMORY : DEVICE_MEMORY));
49 if(!debug_name.empty())
50 set_vulkan_object_name();
53 void VulkanBuffer::sub_data(size_t off, size_t sz, const void *d)
55 Buffer::AsyncTransfer transfer(*static_cast<Buffer *>(this), off, sz);
56 const char *src = static_cast<const char *>(d);
57 copy(src, src+sz, static_cast<char *>(transfer.get_address()));
60 unsigned VulkanBuffer::get_multiplicity() const
62 BufferUsage usage = static_cast<const Buffer *>(this)->usage;
63 return (usage==STREAMING ? device.get_n_frames_in_flight() : 1);
66 bool VulkanBuffer::can_map() const
68 return static_cast<const Buffer *>(this)->usage==STREAMING;
71 void *VulkanBuffer::map()
73 size_t size = static_cast<const Buffer *>(this)->size;
74 mapped_address = device.get_allocator().map(memory_id, 0, size);
75 return mapped_address;
78 bool VulkanBuffer::unmap()
80 device.get_allocator().unmap(mapped_address);
85 void VulkanBuffer::set_debug_name(const string &name)
90 set_vulkan_object_name();
96 void VulkanBuffer::set_vulkan_object_name() const
99 const VulkanFunctions &vk = device.get_functions();
101 VkDebugUtilsObjectNameInfoEXT name_info = { };
102 name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
103 name_info.objectType = VK_OBJECT_TYPE_BUFFER;
104 name_info.objectHandle = reinterpret_cast<uint64_t>(handle);
105 name_info.pObjectName = debug_name.c_str();
106 vk.SetDebugUtilsObjectName(name_info);
111 void Buffer::AsyncTransfer::allocate()
114 dest_addr = static_cast<char *>(buffer.map())+offset;
117 Buffer &buf = buffer;
121 dest_addr = buffer.device.get_transfer_queue().prepare_transfer(&buffer, false, size,
123 buf.device.get_synchronizer().write_buffer(buf.handle, off, sz);
125 [&buf, off, sz](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
126 const VulkanFunctions &vk = buf.device.get_functions();
128 VkBufferCopy region = { };
129 region.srcOffset = src_off;
130 region.dstOffset = off;
132 vk.CmdCopyBuffer(cmd_buf, staging_buf, buf.handle, 1, ®ion);
137 void Buffer::AsyncTransfer::finalize()
142 buffer.device.get_synchronizer().write_buffer(buffer.handle, offset, size, true);
145 buffer.device.get_transfer_queue().finalize_transfer(dest_addr);