Line data Source code
1 : #include "buffer.hpp"
2 :
3 : #include <vk_mem_alloc.h>
4 : #include <vulkan/vulkan_core.h>
5 :
6 : #include <memory>
7 : #include <vulkan/vulkan.hpp>
8 : #include <vulkan/vulkan_enums.hpp>
9 : #include <vulkan/vulkan_structs.hpp>
10 :
11 : namespace wren::vk {
12 :
13 0 : auto Buffer::create(const VmaAllocator& allocator, size_t size,
14 : VkBufferUsageFlags usage,
15 : const std::optional<VmaAllocationCreateFlags>& flags)
16 : -> std::shared_ptr<Buffer> {
17 0 : auto b = std::make_shared<Buffer>(allocator);
18 :
19 0 : VkBufferCreateInfo create_info{};
20 0 : create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
21 0 : create_info.size = size;
22 0 : create_info.usage = static_cast<VkBufferUsageFlags>(usage);
23 :
24 0 : VmaAllocationCreateInfo alloc_info{};
25 0 : alloc_info.usage = VMA_MEMORY_USAGE_AUTO;
26 0 : if (flags) alloc_info.flags = *flags;
27 :
28 0 : VkBuffer buf{};
29 0 : vmaCreateBuffer(allocator, &create_info, &alloc_info, &buf, &b->allocation_,
30 : nullptr);
31 0 : b->buffer_ = buf;
32 :
33 0 : return b;
34 0 : }
35 :
36 0 : auto Buffer::set_data_raw(const void* data, std::size_t size)
37 : -> expected<void> {
38 0 : if (data == nullptr) {
39 0 : return {};
40 : }
41 :
42 0 : const auto res = static_cast<::vk::Result>(
43 0 : vmaCopyMemoryToAllocation(allocator_, data, allocation_, 0, size));
44 0 : if (res != ::vk::Result::eSuccess) {
45 0 : throw std::runtime_error(utils::enum_to_string(res));
46 : }
47 :
48 : // VK_ERR_PROP_VOID(
49 : // static_cast<::::vk::Result>(vmaCopyMemoryToAllocation(
50 : // allocator, data, allocation, 0, size)));
51 0 : return {};
52 0 : }
53 :
54 0 : auto Buffer::copy_buffer(const ::vk::Device& device,
55 : const ::vk::Queue& submit_queue,
56 : const ::vk::CommandPool& command_pool,
57 : const std::shared_ptr<Buffer>& src,
58 : const std::shared_ptr<Buffer>& dst, size_t size)
59 : -> expected<void> {
60 0 : const ::vk::CommandBufferAllocateInfo alloc_info(
61 0 : command_pool, ::vk::CommandBufferLevel::ePrimary, 1);
62 :
63 0 : VK_ERR_PROP(cmd_bufs, device.allocateCommandBuffers(alloc_info));
64 :
65 0 : const auto cmd_buf = cmd_bufs.front();
66 :
67 0 : ::vk::CommandBufferBeginInfo begin_info(
68 0 : ::vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
69 :
70 0 : VK_ERR_PROP_VOID(cmd_buf.begin(begin_info));
71 :
72 0 : ::vk::BufferCopy copy_region(0, 0, size);
73 0 : cmd_buf.copyBuffer(src->get(), dst->get(), copy_region);
74 0 : VK_ERR_PROP_VOID(cmd_buf.end());
75 :
76 0 : ::vk::SubmitInfo submit_info({}, {}, cmd_buf);
77 0 : VK_ERR_PROP_VOID(submit_queue.submit(submit_info));
78 0 : VK_ERR_PROP_VOID(submit_queue.waitIdle());
79 :
80 0 : device.freeCommandBuffers(command_pool, cmd_bufs);
81 :
82 0 : return {};
83 0 : }
84 :
85 0 : Buffer::~Buffer() {
86 0 : unmap();
87 0 : vmaFreeMemory(allocator_, allocation_);
88 0 : }
89 :
90 : } // namespace wren::vk
|