55
66namespace lvk {
77namespace vma {
8- namespace {
9- [[nodiscard]] auto create_buffer (VmaAllocator allocator,
10- VmaAllocationCreateInfo const & allocation_ci,
11- vk::BufferUsageFlags const usage,
12- vk::DeviceSize const size) -> Buffer {
13- if (size == 0 ) {
14- std::println (stderr, " Buffer cannot be 0-sized" );
15- return {};
16- }
17-
18- auto buffer_ci = vk::BufferCreateInfo{};
19- buffer_ci.setSize (size).setUsage (usage);
20- auto vma_buffer_ci = static_cast <VkBufferCreateInfo>(buffer_ci);
21-
22- VmaAllocation allocation{};
23- VkBuffer buffer{};
24- auto allocation_info = VmaAllocationInfo{};
25- auto const result =
26- vmaCreateBuffer (allocator, &vma_buffer_ci, &allocation_ci, &buffer,
27- &allocation, &allocation_info);
28- if (result != VK_SUCCESS) {
29- std::println (stderr, " Failed to create VMA Buffer" );
30- return {};
31- }
32-
33- return RawBuffer{
34- .allocator = allocator,
35- .allocation = allocation,
36- .buffer = buffer,
37- .size = size,
38- .mapped = allocation_info.pMappedData ,
39- };
40- }
41- } // namespace
42-
438void Deleter::operator ()(VmaAllocator allocator) const noexcept {
449 vmaDestroyAllocator (allocator);
4510}
@@ -71,19 +36,55 @@ auto vma::create_allocator(vk::Instance const instance,
7136 throw std::runtime_error{" Failed to create Vulkan Memory Allocator" };
7237}
7338
74- auto vma::create_host_buffer (VmaAllocator allocator,
75- vk::BufferUsageFlags const usage,
76- vk::DeviceSize const size) -> Buffer {
39+ auto vma::create_buffer (BufferCreateInfo const & create_info,
40+ BufferMemoryType const memory_type,
41+ vk::DeviceSize const size) -> Buffer {
42+ if (size == 0 ) {
43+ std::println (stderr, " Buffer cannot be 0-sized" );
44+ return {};
45+ }
46+
7747 auto allocation_ci = VmaAllocationCreateInfo{};
78- allocation_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST;
7948 allocation_ci.flags =
80- VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
81- VMA_ALLOCATION_CREATE_MAPPED_BIT;
82- return create_buffer (allocator, allocation_ci, usage, size);
49+ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
50+ auto usage = create_info.usage ;
51+ if (memory_type == BufferMemoryType::Device) {
52+ allocation_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
53+ // device buffers need to support TransferDst.
54+ usage |= vk::BufferUsageFlagBits::eTransferDst;
55+ } else {
56+ allocation_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST;
57+ // host buffers can provide mapped memory.
58+ allocation_ci.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
59+ }
60+
61+ auto buffer_ci = vk::BufferCreateInfo{};
62+ buffer_ci.setQueueFamilyIndices (create_info.queue_family )
63+ .setSize (size)
64+ .setUsage (usage);
65+ auto vma_buffer_ci = static_cast <VkBufferCreateInfo>(buffer_ci);
66+
67+ VmaAllocation allocation{};
68+ VkBuffer buffer{};
69+ auto allocation_info = VmaAllocationInfo{};
70+ auto const result =
71+ vmaCreateBuffer (create_info.allocator , &vma_buffer_ci, &allocation_ci,
72+ &buffer, &allocation, &allocation_info);
73+ if (result != VK_SUCCESS) {
74+ std::println (stderr, " Failed to create VMA Buffer" );
75+ return {};
76+ }
77+
78+ return RawBuffer{
79+ .allocator = create_info.allocator ,
80+ .allocation = allocation,
81+ .buffer = buffer,
82+ .size = size,
83+ .mapped = allocation_info.pMappedData ,
84+ };
8385}
8486
85- auto vma::create_device_buffer (VmaAllocator allocator,
86- vk::BufferUsageFlags usage,
87+ auto vma::create_device_buffer (BufferCreateInfo const & create_info,
8788 CommandBlock command_block,
8889 ByteSpans const & byte_spans) -> Buffer {
8990 auto const total_size = std::accumulate (
@@ -92,18 +93,14 @@ auto vma::create_device_buffer(VmaAllocator allocator,
9293 return n + bytes.size ();
9394 });
9495
95- // create staging Host Buffer with TransferSrc usage.
96- auto staging_buffer = create_host_buffer (
97- allocator, vk::BufferUsageFlagBits::eTransferSrc, total_size);
96+ auto staging_ci = create_info;
97+ staging_ci.usage = vk::BufferUsageFlagBits::eTransferSrc;
9898
99+ // create staging Host Buffer with TransferSrc usage.
100+ auto staging_buffer =
101+ create_buffer (create_info, BufferMemoryType::Host, total_size);
99102 // create the Device Buffer, ensuring TransferDst usage.
100- usage |= vk::BufferUsageFlagBits::eTransferDst;
101- auto allocation_ci = VmaAllocationCreateInfo{};
102- allocation_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
103- allocation_ci.flags =
104- VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
105- auto ret = create_buffer (allocator, allocation_ci, usage, total_size);
106-
103+ auto ret = create_buffer (create_info, BufferMemoryType::Device, total_size);
107104 // can't do anything if either buffer creation failed.
108105 if (!staging_buffer.get ().buffer || !ret.get ().buffer ) { return {}; }
109106
@@ -132,4 +129,44 @@ auto vma::create_device_buffer(VmaAllocator allocator,
132129
133130 return ret;
134131}
132+
133+ auto vma::create_image (VmaAllocator allocator,
134+ ImageCreateInfo const & create_info) -> Image {
135+ if (create_info.extent .width == 0 || create_info.extent .height == 0 ) {
136+ std::println (stderr, " Images cannot have 0 width or height" );
137+ return {};
138+ }
139+ auto image_ci = vk::ImageCreateInfo{};
140+ image_ci.setImageType (vk::ImageType::e2D)
141+ .setExtent ({create_info.extent .width , create_info.extent .height , 1 })
142+ .setFormat (create_info.format )
143+ .setUsage (create_info.usage )
144+ .setArrayLayers (1 )
145+ .setMipLevels (create_info.levels )
146+ .setSamples (vk::SampleCountFlagBits::e1 )
147+ .setTiling (vk::ImageTiling::eOptimal)
148+ .setInitialLayout (vk::ImageLayout::eUndefined)
149+ .setQueueFamilyIndices (create_info.queue_family );
150+ auto const vk_image_ci = static_cast <VkImageCreateInfo>(image_ci);
151+
152+ auto allocation_ci = VmaAllocationCreateInfo{};
153+ allocation_ci.usage = VMA_MEMORY_USAGE_AUTO;
154+ VkImage image{};
155+ VmaAllocation allocation{};
156+ auto const result = vmaCreateImage (allocator, &vk_image_ci, &allocation_ci,
157+ &image, &allocation, {});
158+ if (result != VK_SUCCESS) {
159+ std::println (stderr, " Failed to create VMA Image" );
160+ return {};
161+ }
162+
163+ return RawImage{
164+ .allocator = allocator,
165+ .allocation = allocation,
166+ .image = image,
167+ .extent = create_info.extent ,
168+ .format = create_info.format ,
169+ .levels = create_info.levels ,
170+ };
171+ }
135172} // namespace lvk
0 commit comments