Skip to content

Commit 56f812d

Browse files
committed
feat: attempt implement a better allocator abstraction
1 parent 9b592bb commit 56f812d

12 files changed

Lines changed: 66 additions & 53 deletions

include/quark/vk/buffer.hpp

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#pragma once
22

33
#include <cstddef>
4+
#include <utility>
45

56
#include <quark/utils/raii.hpp>
67
#include <quark/utils/result.hpp>
8+
#include <quark/vk/allocator.hpp>
79
#include <vk_mem_alloc.h>
810
#include <vulkan/vulkan_core.h>
911

@@ -13,43 +15,35 @@ class Buffer final {
1315

1416
public:
1517
struct CreateInfo {
16-
VmaAllocator allocator = nullptr;
18+
const Allocator *allocator = nullptr;
1719
VkDeviceSize size{};
1820
VkBufferUsageFlags usage{};
19-
VmaMemoryUsage memory_usage = VMA_MEMORY_USAGE_AUTO;
21+
VmaMemoryUsage memory_usage{VMA_MEMORY_USAGE_AUTO};
2022
VmaAllocationCreateFlags allocation_flags{};
21-
VkSharingMode sharing_mode = VK_SHARING_MODE_EXCLUSIVE;
23+
VkSharingMode sharing_mode{VK_SHARING_MODE_EXCLUSIVE};
2224
};
2325

2426
Buffer() = default;
2527
~Buffer() { destroy(); }
2628

27-
QUARK_NO_COPY(Buffer); // do we want copy or not?
29+
QUARK_NO_COPY(Buffer);
2830

2931
Buffer(Buffer &&other) noexcept
30-
: allocator_(other.allocator_), buffer_(other.buffer_),
31-
allocation_(other.allocation_), size_(other.size_) {
32-
other.allocator_ = nullptr;
33-
other.buffer_ = VK_NULL_HANDLE;
34-
other.allocation_ = nullptr;
35-
other.size_ = 0;
36-
}
32+
: allocator_(std::exchange(other.allocator_, nullptr)),
33+
buffer_(std::exchange(other.buffer_, VK_NULL_HANDLE)),
34+
allocation_(std::exchange(other.allocation_, nullptr)),
35+
size_(std::exchange(other.size_, 0)) {}
3736

3837
Buffer &operator=(Buffer &&other) noexcept {
3938
if (this == &other) {
4039
return *this;
4140
}
4241

4342
this->destroy();
44-
allocator_ = other.allocator_;
45-
buffer_ = other.buffer_;
46-
allocation_ = other.allocation_;
47-
size_ = other.size_;
48-
49-
other.allocator_ = nullptr;
50-
other.buffer_ = VK_NULL_HANDLE;
51-
other.allocation_ = nullptr;
52-
other.size_ = 0;
43+
allocator_ = std::exchange(other.allocator_, nullptr);
44+
buffer_ = std::exchange(other.buffer_, VK_NULL_HANDLE);
45+
allocation_ = std::exchange(other.allocation_, nullptr);
46+
size_ = std::exchange(other.size_, 0);
5347
return *this;
5448
}
5549

include/quark/vk/device/details/device.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
#include <cstdint>
44
#include <quark/utils/raii.hpp>
55
#include <quark/utils/result.hpp>
6+
#include <quark/vk/allocator.hpp>
67
#include <quark/vk/device/details/device_capabilities.hpp>
78
#include <vector>
8-
#include <vk_mem_alloc.h>
99
#include <vulkan/vulkan_core.h>
1010

1111
namespace quark::vk::details {
@@ -65,10 +65,14 @@ class Device final {
6565
return capabilities_;
6666
}
6767

68-
[[nodiscard]] VmaAllocator vma_allocator() const noexcept {
68+
[[nodiscard]] const Allocator &allocator() const noexcept {
6969
return allocator_;
7070
}
7171

72+
[[nodiscard]] VmaAllocator vma_allocator() const noexcept {
73+
return allocator_.handle();
74+
}
75+
7276
private:
7377
struct DeviceSelection {
7478
VkPhysicalDevice physical_device{VK_NULL_HANDLE};
@@ -106,7 +110,7 @@ class Device final {
106110
uint32_t graphics_queue_family_index_ = 0;
107111
uint32_t present_queue_family_index_ = 0;
108112
const VkAllocationCallbacks *alloc_ = nullptr;
109-
VmaAllocator allocator_ = nullptr;
113+
Allocator allocator_;
110114
DeviceCapabilities capabilities_{};
111115
};
112116

include/quark/vk/device/device_bundle.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <quark/utils/raii.hpp>
44
#include <quark/utils/result.hpp>
5+
#include <quark/vk/allocator.hpp>
56
#include <quark/vk/device/details/device.hpp>
67
#include <quark/vk/device/details/device_capabilities.hpp>
78
#include <vulkan/vulkan_core.h>
@@ -35,6 +36,7 @@ class DeviceBundle final {
3536
[[nodiscard]] uint32_t graphics_queue_family_index() const noexcept;
3637
[[nodiscard]] uint32_t present_queue_family_index() const noexcept;
3738
[[nodiscard]] details::DeviceCapabilities capabilities() const noexcept;
39+
[[nodiscard]] const Allocator &allocator() const noexcept;
3840
[[nodiscard]] VmaAllocator vma_allocator() const noexcept;
3941

4042
private:

include/quark/vk/triangle_renderer.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
#include <quark/platform/shader/details/shader_registry.hpp>
44
#include <quark/utils/raii.hpp>
55
#include <quark/utils/result.hpp>
6+
#include <quark/vk/allocator.hpp>
67
#include <quark/vk/device/device_view.hpp>
78
#include <quark/vk/pipeline/graphics_pipeline_bundle.hpp>
89
#include <quark/vk/pipeline/graphics_pipeline_desc.hpp>
910
#include <quark/vk/triangle_vertex_buffer.hpp>
10-
#include <vk_mem_alloc.h>
1111
#include <vulkan/vulkan_core.h>
1212

1313
namespace quark::vk {
@@ -16,7 +16,7 @@ class TriangleRenderer final {
1616
public:
1717
struct CreateInfo {
1818
DeviceView device{};
19-
VmaAllocator allocator = nullptr;
19+
const Allocator *allocator = nullptr;
2020
RetirementQueue *retire_queue = nullptr;
2121
VkExtent2D extent{};
2222
VkFormat color_format{VK_FORMAT_UNDEFINED};

include/quark/vk/triangle_vertex_buffer.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <quark/utils/raii.hpp>
66
#include <quark/utils/result.hpp>
7+
#include <quark/vk/allocator.hpp>
78
#include <quark/vk/buffer.hpp>
89

910
namespace quark::vk {
@@ -15,7 +16,7 @@ class TriangleVertexBuffer final {
1516

1617
QUARK_NO_COPY_NO_MOVE(TriangleVertexBuffer);
1718

18-
util::Status create(VmaAllocator allocator);
19+
util::Status create(const Allocator &allocator);
1920
void destroy() noexcept;
2021

2122
void bind(VkCommandBuffer command_buffer) const noexcept;

src/backend/vulkan/device/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_library(
22
quark_backend_vulkan_device STATIC
3+
allocator.cpp
34
device.cpp
45
device_feature_chain_builder.cpp
56
device_bundle.cpp

src/backend/vulkan/device/buffer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ util::Status Buffer::create(const Buffer::CreateInfo &ci) {
1212

1313
QUARK_ENSURE(ci.allocator != nullptr,
1414
QUARK_ERR(util::Errc::InvalidArg, "Buffer allocator is null"));
15+
QUARK_ENSURE(
16+
ci.allocator->valid(),
17+
QUARK_ERR(util::Errc::InvalidArg, "Buffer allocator is not created"));
1518
QUARK_ENSURE(ci.size > 0,
1619
QUARK_ERR(util::Errc::InvalidArg, "Buffer size must be > 0"));
1720
QUARK_ENSURE(ci.usage != 0,
1821
QUARK_ERR(util::Errc::InvalidArg, "Buffer usage must be set"));
1922

23+
VmaAllocator allocator = ci.allocator->handle();
24+
2025
VkBufferCreateInfo buffer_info{};
2126
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2227
buffer_info.size = ci.size;
@@ -27,10 +32,10 @@ util::Status Buffer::create(const Buffer::CreateInfo &ci) {
2732
alloc_info.usage = ci.memory_usage;
2833
alloc_info.flags = ci.allocation_flags;
2934

30-
QUARK_VK_TRY(vmaCreateBuffer(ci.allocator, &buffer_info, &alloc_info,
31-
&buffer_, &allocation_, nullptr));
35+
QUARK_VK_TRY(vmaCreateBuffer(allocator, &buffer_info, &alloc_info, &buffer_,
36+
&allocation_, nullptr));
3237

33-
allocator_ = ci.allocator;
38+
allocator_ = allocator;
3439
size_ = ci.size;
3540
QUARK_OK();
3641
}

src/backend/vulkan/device/device.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,27 +90,25 @@ util::Status Device::create(const Device::CreateInfo &ci) {
9090
present_queue_family_index_ = graphics_queue_family_index_;
9191
}
9292

93-
VmaAllocatorCreateInfo allocator_info{};
94-
allocator_info.physicalDevice = physical_device_;
95-
allocator_info.device = device_;
96-
allocator_info.instance = ci.instance;
97-
allocator_info.pAllocationCallbacks = alloc_;
98-
allocator_info.vulkanApiVersion = capabilities_.api_version;
99-
100-
VkResult allocator_result = vmaCreateAllocator(&allocator_info, &allocator_);
101-
if (allocator_result != VK_SUCCESS) {
93+
util::Status allocator_status = allocator_.create({
94+
.instance = ci.instance,
95+
.physical_device = physical_device_,
96+
.device = device_,
97+
.allocation_callbacks = alloc_,
98+
.vulkan_api_version = capabilities_.api_version,
99+
});
100+
if (!allocator_status) {
102101
destroy();
103-
return util::unexpected(vk_error(allocator_result, "vmaCreateAllocator"));
102+
// return std::move(allocator_status); // uncomment this line to see a nice
103+
// lint.
104+
return allocator_status;
104105
}
105106

106107
QUARK_OK();
107108
}
108109

109110
void Device::destroy() noexcept {
110-
if (allocator_ != nullptr) {
111-
vmaDestroyAllocator(allocator_);
112-
allocator_ = nullptr;
113-
}
111+
allocator_.destroy();
114112

115113
if (device_ != VK_NULL_HANDLE) {
116114
vkDestroyDevice(device_, nullptr);

src/backend/vulkan/device/device_bundle.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,17 @@ uint32_t DeviceBundle::graphics_queue_family_index() const noexcept {
5555
}
5656

5757
uint32_t DeviceBundle::present_queue_family_index() const noexcept {
58-
return device_.graphics_queue_family_index();
58+
return device_.present_queue_family_index();
5959
}
6060

6161
details::DeviceCapabilities DeviceBundle::capabilities() const noexcept {
6262
return device_.capabilities();
6363
}
6464

65+
const Allocator &DeviceBundle::allocator() const noexcept {
66+
return device_.allocator();
67+
}
68+
6569
VmaAllocator DeviceBundle::vma_allocator() const noexcept {
6670
return device_.vma_allocator();
6771
}

src/backend/vulkan/triangle_renderer.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
#include <quark/vk/pipeline/vertex_layout.hpp>
66
#include <quark/vk/triangle_renderer.hpp>
77

8-
98
namespace quark::vk {
109

1110
util::Status TriangleRenderer::create(const TriangleRenderer::CreateInfo &ci) {
1211
destroy();
1312

13+
QUARK_ENSURE(
14+
ci.allocator != nullptr,
15+
QUARK_ERR(util::Errc::InvalidArg, "Triangle renderer allocator is null"));
16+
1417
QUARK_TRY_STATUS(shader_registry_.create({.device = ci.device.device}));
1518

1619
ShaderHandle vert_shader{};
@@ -44,12 +47,13 @@ util::Status TriangleRenderer::create(const TriangleRenderer::CreateInfo &ci) {
4447
},
4548
};
4649

47-
const std::array<ColorAttachmentDesc, 1> color_attachments{ColorAttachmentDesc{
48-
.format = ci.color_format,
49-
}};
50+
const std::array<ColorAttachmentDesc, 1> color_attachments{
51+
ColorAttachmentDesc{
52+
.format = ci.color_format,
53+
}};
5054

5155
const std::array<VkDynamicState, 2> dynamic_states{VK_DYNAMIC_STATE_VIEWPORT,
52-
VK_DYNAMIC_STATE_SCISSOR};
56+
VK_DYNAMIC_STATE_SCISSOR};
5357

5458
const GraphicsPipelineDesc desc{
5559
.stages = stages,
@@ -72,7 +76,7 @@ util::Status TriangleRenderer::create(const TriangleRenderer::CreateInfo &ci) {
7276
.desc = &desc,
7377
}));
7478

75-
QUARK_TRY_STATUS(vertex_buffer_.create(ci.allocator));
79+
QUARK_TRY_STATUS(vertex_buffer_.create(*ci.allocator));
7680
QUARK_OK();
7781
}
7882

0 commit comments

Comments
 (0)