X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Fbuffer_backend.cpp;fp=source%2Fbackends%2Fvulkan%2Fbuffer_backend.cpp;h=4207e87d35d96a4bde10ff3dc642eb02f9c90267;hb=99ca354f18119f82f1adeca100cd665a8f640317;hp=0000000000000000000000000000000000000000;hpb=4cd245dafe6a7ee5c93edca5aee2d146f1155309;p=libs%2Fgl.git diff --git a/source/backends/vulkan/buffer_backend.cpp b/source/backends/vulkan/buffer_backend.cpp new file mode 100644 index 00000000..4207e87d --- /dev/null +++ b/source/backends/vulkan/buffer_backend.cpp @@ -0,0 +1,127 @@ +#include "buffer.h" +#include "buffer_backend.h" +#include "device.h" +#include "vulkan.h" + +using namespace std; + +namespace Msp { +namespace GL { + +VulkanBuffer::VulkanBuffer(): + device(Device::get_current()) +{ } + +VulkanBuffer::VulkanBuffer(VulkanBuffer &&other): + device(other.device), + handle(other.handle), + memory_id(other.memory_id), + mapped_address(other.mapped_address), + debug_name(move(other.debug_name)) +{ + other.handle = 0; + other.memory_id = 0; + other.mapped_address = 0; +} + +VulkanBuffer::~VulkanBuffer() +{ + if(handle) + device.get_destroy_queue().destroy(handle, memory_id); +} + +void VulkanBuffer::allocate() +{ + const Buffer &self = *static_cast(this); + const VulkanFunctions &vk = device.get_functions(); + + VkBufferCreateInfo buffer_info = { }; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = self.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; + + vk.CreateBuffer(buffer_info, handle); + + memory_id = device.get_allocator().allocate(handle, (self.usage==STREAMING ? STREAMING_MEMORY : DEVICE_MEMORY)); + + if(!debug_name.empty()) + set_vulkan_object_name(); +} + +void VulkanBuffer::sub_data(size_t off, size_t sz, const void *d) +{ + 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); + + VkBufferMemoryBarrier barrier = { }; + barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.buffer = handle_cast<::VkBuffer>(handle); + barrier.offset = off; + barrier.size = sz; + + vk.CmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + 0, 0, 0, 1, &barrier, 0, 0); + }); + + const char *src = static_cast(d); + copy(src, src+sz, static_cast(staging)); +} + +bool VulkanBuffer::can_map() const +{ + return static_cast(this)->usage==STREAMING; +} + +void *VulkanBuffer::map() +{ + size_t size = static_cast(this)->size; + mapped_address = device.get_allocator().map(memory_id, 0, size); + return mapped_address; +} + +bool VulkanBuffer::unmap() +{ + device.get_allocator().unmap(mapped_address); + mapped_address = 0; + return true; +} + +void VulkanBuffer::set_debug_name(const string &name) +{ +#ifdef DEBUG + debug_name = name; + if(handle) + set_vulkan_object_name(); +#else + (void)name; +#endif +} + +void VulkanBuffer::set_vulkan_object_name() const +{ +#ifdef DEBUG + const VulkanFunctions &vk = device.get_functions(); + + VkDebugUtilsObjectNameInfoEXT name_info = { }; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.objectType = VK_OBJECT_TYPE_BUFFER; + name_info.objectHandle = reinterpret_cast(handle); + name_info.pObjectName = debug_name.c_str(); + vk.SetDebugUtilsObjectName(name_info); +#endif +} + +} // namespace GL +} // namespace Msp