-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstance.cppm
More file actions
144 lines (124 loc) · 6.35 KB
/
instance.cppm
File metadata and controls
144 lines (124 loc) · 6.35 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
module;
#include <span>
#include <vector>
#include <vulkan/vulkan.h>
export module vk:instance;
export import :types;
export import :utilities;
export namespace vk {
inline namespace v1 {
/**
* @brief vk::instance represents VkInstance to initialize the vulkan API.
*
* Provides configuration settings that can be applied to the application
* and the vulkan debug utility for the validation layers
*/
class instance {
public:
/**
* @param p_config sets the application information that vulkan has
* optionally.
* @param p_debug_message_utils is for setting up vulkan's utility
* tooling for debugging and enabling validation layers
*/
instance(const application_params& p_config,
const debug_message_utility& p_debug_message_utils) {
VkApplicationInfo app_info = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr,
.applicationVersion = 1,
.pEngineName = p_config.name.c_str(),
.engineVersion = 1,
.apiVersion = static_cast<uint32_t>(p_config.version),
};
VkInstanceCreateInfo instance_ci = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.pApplicationInfo = &app_info
};
// Setting up validation layers properties
uint32_t layer_count = 0;
std::vector<VkLayerProperties> layer_properties;
vkEnumerateInstanceLayerProperties(&layer_count, nullptr);
// std::vector<VkLayerProperties> layer_properties(layer_count);
layer_properties.resize(layer_count);
vkEnumerateInstanceLayerProperties(&layer_count,
layer_properties.data());
for (const VkLayerProperties property : layer_properties) {
m_layer_properties.emplace_back(property.layerName,
property.specVersion,
property.implementationVersion,
property.description);
}
// Setting up instance extensions
instance_ci.enabledExtensionCount =
static_cast<uint32_t>(p_config.extensions.size());
instance_ci.ppEnabledExtensionNames = p_config.extensions.data();
#if defined(__APPLE__)
instance_ci.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif
// Only execute this if we are in the debug build
#if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG)
// Setting up validation layers
instance_ci.enabledLayerCount =
static_cast<uint32_t>(p_config.validations.size());
instance_ci.ppEnabledLayerNames = p_config.validations.data();
VkDebugUtilsMessengerCreateInfoEXT debug_create_info = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
.messageSeverity = static_cast<VkDebugUtilsMessageSeverityFlagsEXT>(p_debug_message_utils.severity),
.messageType = static_cast<VkDebugUtilsMessageTypeFlagsEXT>(p_debug_message_utils.message_type),
.pfnUserCallback = p_debug_message_utils.callback,
};
// This is to invoke the vulkan debug utils if it is a valid callback
// To ensure that we are not using an invalid debug callback
if (p_debug_message_utils.callback != nullptr) {
// instance_ci.pNext = (VkDebugUtilsMessengerCreateInfoEXT*)&debug_create_info;
instance_ci.pNext = reinterpret_cast<VkDebugUtilsMessengerCreateInfoEXT*>(&debug_create_info);
}
else {
instance_ci.pNext = nullptr;
}
#else
instance_ci.enabledLayerCount = 0;
instance_ci.ppEnabledLayerNames = nullptr;
instance_ci.pNext = nullptr;
#endif
vk_check(vkCreateInstance(&instance_ci, nullptr, &m_instance),
"vkCreateInstance");
// Set the debug utility function pointer if we are in the debug build.
#if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG)
// This needs to be created after the VkInstance is or else it wont be applied the debug information during validation layer error message execution
m_vk_set_debug_utils_object_name_ext = reinterpret_cast<PFN_vkSetDebugUtilsObjectNameEXT>(vkGetInstanceProcAddr(m_instance, "vkSetDebugUtilsObjectNameEXT"));
#endif
}
//! @return true if a valid VkInstance
[[nodiscard]] bool alive() const { return !m_instance; }
//! @return available validation layers
std::span<const layer_properties> validation() {
return m_layer_properties;
}
/**
* @brief returns function pointer to allow for setting debug object name
*
*
* This allows for utilizing vkSetDebugUtilsObjectNameEXT during debug builds
*
* This allows for setting up object names that is useful to the programmer when a validation layer error message occurs unexpectedly
*
*/
[[nodiscard]] PFN_vkSetDebugUtilsObjectNameEXT get_debug_object_name() const {
return m_vk_set_debug_utils_object_name_ext;
}
operator VkInstance() { return m_instance; }
operator VkInstance() const { return m_instance; }
//! @brief Invokes the destruction of the VkInstance.
void destroy() {}
private:
VkInstance m_instance = nullptr;
std::vector<layer_properties> m_layer_properties{};
// This needs to be set or else it becomes nullptr
PFN_vkSetDebugUtilsObjectNameEXT m_vk_set_debug_utils_object_name_ext;
};
};
};