1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include <memory>
#include <vulkan/vulkan_core.h>
#include <vulkan/vk_enum_string_helper.h>
#include <vk_mem_alloc.h>
#include <spdlog/spdlog.h>
#include <cstdint>
#include <vector>
#include <string>
#define CHECK_VULKAN(result) \
do { \
VkResult res = result; \
if (res != VK_SUCCESS) { \
spdlog::error("Vulkan error: {}", string_VkResult(res)); \
abort(); \
} \
} while (0)
namespace iris {
struct Buffer_t {
VkBuffer buffer;
VkDevice device;
VmaAllocator allocator;
VmaAllocation allocation;
VkBufferUsageFlags flags;
VkDeviceSize size;
void *mapped_data = nullptr;
void* map();
void unmap();
void release();
~Buffer_t() { release(); }
};
typedef std::shared_ptr<Buffer_t> Buffer;
struct Texture2D_t {
VkImage image;
VkDevice device;
VmaAllocator allocator;
VmaAllocation allocation;
VkImageView image_view;
VkImageLayout layout;
VkImageUsageFlags flags;
VkExtent2D extent;
void release();
~Texture2D_t() { release(); }
};
typedef std::shared_ptr<Texture2D_t> Texture2D;
// This is a really brute-force implementation,
// every command pool contains only 1 command buffer
struct CommandBuffer {
VkDevice device;
VkCommandPool pool;
VkCommandBuffer buffer;
VkFence fence;
VkQueue queue;
CommandBuffer(VkDevice device, uint32_t queue_family_index, VkQueue queue);
void destroy();
void begin(VkCommandBufferUsageFlags flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
void submit_sync();
~CommandBuffer() { destroy(); }
};
struct AsyncCommandBuffer {
VkDevice device;
VkCommandPool pool;
VkCommandBuffer buffer;
VkFence fence;
VkQueue queue;
AsyncCommandBuffer(VkDevice device, uint32_t queue_family_index, VkQueue queue);
void destroy();
~AsyncCommandBuffer() { destroy(); }
};
struct Device {
VkInstance instance;
VkPhysicalDevice physical_device;
VkDevice device;
uint32_t main_queue_family_index;
VkQueue graphics_queue;
VmaAllocator allocator;
#ifdef USE_VULKAN_VALIDATION_LAYERS
VkDebugReportCallbackEXT debugReportCallback;
VkDebugUtilsMessengerEXT debugUtilsMessenger;
#endif
Device() = delete;
Device(
std::vector<std::string> layers,
std::vector<std::string> instance_extensions);
void destroy();
Buffer create_buffer(
VkDeviceSize size,
VkBufferUsageFlags usage,
VmaAllocationCreateInfo create_info = {
.usage = VMA_MEMORY_USAGE_AUTO,
});
Texture2D create_texture(
VkExtent2D extent,
VkFormat format,
VkImageUsageFlags usage,
VmaAllocationCreateInfo create_info = {
.usage = VMA_MEMORY_USAGE_AUTO,
});
Texture2D create_texture_from_image(
const char* filename,
VkFormat format,
VkImageUsageFlags usage,
VmaAllocationCreateInfo create_info = {
.usage = VMA_MEMORY_USAGE_AUTO,
});
CommandBuffer create_command_buffer();
AsyncCommandBuffer create_async_command_buffer();
};
} // namespace iris
|