SpiecsEngine
 
Loading...
Searching...
No Matches
VulkanInstance.cpp
Go to the documentation of this file.
1/**
2* @file VulkanInstance.cpp.
3* @brief The VulkanInstance Class Implementation.
4* @author Spices.
5*/
6
7#include "Pchheader.h"
9#include "Core/Library/StringLibrary.h"
10#include "Debugger/Perf/NsightPerfGPUProfilerHUD.h"
11
12namespace Spices {
13
15 VulkanState& vulkanState ,
16 const std::string& name ,
17 const std::string& engineName
18 )
19 : VulkanObject(vulkanState)
20 {
22
23 /**
24 * @brief Create VkApplicationInfo struct.
25 */
26 VkApplicationInfo appInfo {};
27 appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
28 appInfo.pApplicationName = name.c_str();
29 appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
30 appInfo.pEngineName = engineName.c_str();
31 appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
32 appInfo.apiVersion = VK_API_VERSION_1_3;
33
34 /**
35 * @brief Create VkInstanceCreateInfo struct.
36 */
37 VkInstanceCreateInfo createInfo {};
38 createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
39 createInfo.pApplicationInfo = &appInfo;
40
41 /**
42 * @brief Get all instance extension requirements our engine needede.
43 */
45
46 /**
47 * @brief Iter all our extensions, check whether all satisfied or not.
48 */
50 {
51 std::stringstream ss;
52 ss << "Instance Extension not Satisfied";
53
54 SPICES_CORE_ERROR(ss.str());
55 }
56
57 /**
58 * @brief Set instance extension.
59 */
60 createInfo.enabledExtensionCount = static_cast<uint32_t>(m_ExtensionProperties.size());
61 createInfo.ppEnabledExtensionNames = m_ExtensionProperties.data();
62
63 /**
64 * @brief Get all instance layer requirements our engine needede.
65 */
67
68 /**
69 * @brief Iter all our layers, check whether all satisfied or not.
70 */
72
73 /**
74 * @brief Set instance layer.
75 */
76 createInfo.enabledLayerCount = static_cast<uint32_t>(m_LayerProperties.size());
77 createInfo.ppEnabledLayerNames = m_LayerProperties.data();
78
79 /**
80 * @brief Set VkDebugUtilsMessengerCreateInfoEXT.
81 */
83
84 /**
85 * @brief Enable Shader Debug Feature.
86 * Enable DescriptorSet Index Check.
87 */
88 std::vector<VkValidationFeatureEnableEXT> validationFeatureEnable;
89
90#if 0 // Set to 1 if want print message in shader.(Cause Device Wait 1s suspend.)
91
92 validationFeatureEnable.push_back(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT);
93
94#endif
95
96 VkValidationFeaturesEXT validationFeatures{};
97 validationFeatures.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
98 validationFeatures.enabledValidationFeatureCount = static_cast<uint32_t>(validationFeatureEnable.size());
99 validationFeatures.pEnabledValidationFeatures = validationFeatureEnable.data();
100
101#ifdef SPICES_DEBUG
102
103 m_DebugMessengerCreateInfo.pNext = &validationFeatures;
104
105#endif
106
107 createInfo.pNext = &m_DebugMessengerCreateInfo;
108
109 /**
110 * @brief Create instance and set it global.
111 */
112 VK_CHECK(vkCreateInstance(&createInfo, nullptr, &vulkanState.m_Instance))
113
114 /**
115 * @brief Init Vulkan Functions.
116 */
117 vulkanState.m_VkFunc.Init(vulkanState.m_Instance);
118
119 /**
120 * @brief Set Vulkan's debug message callback function pointer.
121 */
123
124 /**
125 * @brief Create Surface.
126 */
128 }
129
131 {
133
134 /**
135 * @brief Destroy the Vulkan Surface Object.
136 */
137 vkDestroySurfaceKHR(m_VulkanState.m_Instance, m_VulkanState.m_Surface, nullptr);
138 m_VulkanState.m_Surface = nullptr;
139
140 /**
141 * @brief Destroy Vulkan's debug message callback function pointer.
142 * Working with DEBUG mode.
143 */
144#ifdef SPICES_DEBUG
145
146 /**
147 * @brief Destroy Debug Utils Messenger.
148 */
149 m_VulkanState.m_VkFunc.vkDestroyDebugUtilsMessengerEXT(m_VulkanState.m_Instance, m_DebugMessenger, nullptr);
150
151#endif
152
153 /**
154 * @brief Destroy the Vulkan Instance Object.
155 */
156 vkDestroyInstance(m_VulkanState.m_Instance, nullptr);
157 m_VulkanState.m_Instance = nullptr;
158 }
159
161 {
163
164 m_ExtensionProperties.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
165 m_ExtensionProperties.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
166
167 /**
168 * @brief Get glfw extensions requirements.
169 */
170 uint32_t glfwExtensionCount = 0;
171 const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
172
173 /**
174 * @brief Combine glfw extensions requirements.
175 */
176 for (uint32_t i = 0; i < glfwExtensionCount; i++)
177 {
178 m_ExtensionProperties.push_back(*glfwExtensions);
179 glfwExtensions++;
180 }
181
182 /**
183 * @brief Combine with our extensions requirements.
184 * @todo Our instance extensions requirements.
185 */
186#ifdef SPICES_DEBUG
187
188 /**
189 * @brief To enable validation layer, we need this instance extension.
190 */
191 m_ExtensionProperties.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
192
193#endif
194
195 /**
196 * @brief Add Nsight Perf Extensions.
197 */
198 NSIGHTPERF_GPUPROFILERHUD_QUERYINSTANCEEXTENSION(m_ExtensionProperties, VK_API_VERSION_1_3)
199
200 }
201
203 {
205
206 /**
207 * @brief Get all instance extensions nums.
208 */
209 uint32_t extensionCount = 0;
210 vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
211
212 /**
213 * @brief Get all instance extensions that supported.
214 */
215 std::vector<VkExtensionProperties> availableExtensions(extensionCount);
216 vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions.data());
217
218 /**
219 * @brief Check whether all extensions satisfied.
220 */
221 std::set<std::string> requiredExtensions(m_ExtensionProperties.begin(), m_ExtensionProperties.end());
222
223 for (const auto& extension : availableExtensions)
224 {
225 requiredExtensions.erase(extension.extensionName);
226 }
227
228 if (!requiredExtensions.empty())
229 {
230 for (auto& set : requiredExtensions)
231 {
232 std::stringstream ss;
233 ss << "Instance Extension Required: " << set << ", Which is not satisfied";
234
235 SPICES_CORE_WARN(ss.str())
236 }
237 }
238
239 return requiredExtensions.empty();
240 }
241
243 {
245
246#ifdef SPICES_DEBUG
247
248 /**
249 * @brief Combine with our extensions requirements.
250 */
251 m_LayerProperties.push_back("VK_LAYER_KHRONOS_validation");
252
253#endif
254
255 }
256
258 {
260
261 /**
262 * @brief Get all layer extensions nums.
263 */
264 uint32_t layerCount;
265 vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
266
267 /**
268 * @brief Get all instance layer that supported.
269 */
270 std::vector<VkLayerProperties> availableLayers(layerCount);
271 vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
272
273 /**
274 * @brief Check whether all layer satisfied.
275 */
276 std::set<std::string> requiredLayers(m_LayerProperties.begin(), m_LayerProperties.end());
277
278 for (const auto& layer : availableLayers)
279 {
280 requiredLayers.erase(layer.layerName);
281 }
282
283 if (!requiredLayers.empty())
284 {
285 for (auto& set : requiredLayers)
286 {
287 std::stringstream ss;
288 ss << "Instance Layer Required: " << set << ", Which is not satisfied";
289
290 SPICES_CORE_WARN(ss.str())
291 }
292 }
293
294 return requiredLayers.empty();
295 }
296
298 {
300
301#ifdef SPICES_DEBUG
302
303 /**
304 * @brief Create DebugUtilsMessenger.
305 */
306 m_VulkanState.m_VkFunc.vkCreateDebugUtilsMessengerEXT(m_VulkanState.m_Instance, &m_DebugMessengerCreateInfo, nullptr, &m_DebugMessenger);
307
308#endif
309
310 }
311
313 {
315
316 /**
317 * @brief Create surface and set it global.
318 * @note Init with Window's size, but we need resize it to viewport's size after.
319 */
320 VK_CHECK(glfwCreateWindowSurface(m_VulkanState.m_Instance, m_VulkanState.m_Windows, nullptr, &m_VulkanState.m_Surface))
321 }
322
327 void* pUserData
328 )
329 {
331
332 /**
333 * @brief Format string.
334 */
336
337 ss <<
338 "validation layer:\n " <<
339 "MessageIdNumber: " <<
341 "\n MessageIdName: " <<
343
345 {
346 ss << "\n CmdLabelName: " <<
348 }
349
350 ss <<
351 "\n Message: " <<
353
354 switch (messageSeverity)
355 {
356 /**
357 * @brief verbose, unknown level.
358 */
361 break;
362
363 /**
364 * @brief info level.
365 */
368 break;
369
370 /**
371 * @brief warning level.
372 */
375 break;
376
377 /**
378 * @brief error level.
379 */
382 break;
383
385 break;
386
387 default:
388 break;
389 }
390
391 return VK_FALSE;
392 }
393
395 {
397
398 /**
399 * @brief Instanced a VkDebugUtilsMessengerCreateInfoEXT with default value.
400 */
403
409
414
416 m_DebugMessengerCreateInfo.pUserData = nullptr; // Optional
418 }
419}
#define NSIGHTPERF_GPUPROFILERHUD_QUERYINSTANCEEXTENSION(...)
#define SPICES_PROFILE_ZONE
#define VK_CHECK(expr)
Vulkan Check macro. Verify Vulkan API Effectiveness.
Definition VulkanUtils.h:68
void SetVulkanDebugCallbackFuncPointer()
Set Vulkan's debug message callback function pointer. Working with DEBUG mode.
virtual ~VulkanInstance() override
Destructor Function.
void CreateVulkanSurface() const
Create a Surface Object.
VulkanInstance(VulkanState &vulkanState, const std::string &name, const std::string &engineName)
Constructor Function. Create vkInstance and vkSurface.
bool CheckExtensionRequirementsSatisfied()
Iter all our extensions, check whether all satisfied or not.
void FillDebugMessengerCreateInfo()
Set m_DebugMessengerCreateInfo variable.
void GetExtensionRequirements()
Get all instance extension requirements our engine needed. Source 1 : glfw requirements....
bool ChecklayerRequirementsSatisfied()
Iter all our layers, check whether all satisfied or not.
void GetLayerRequirements()
Get all instance layer requirements our engine needed. Source 1 : user Setting.
VulkanInstance Class. This class defines the VulkanInstance behaves. This class is just a wrapper of ...
VulkanState & m_VulkanState
The global VulkanState Referenced from VulkanRenderBackend.
VulkanObject(VulkanState &vulkanState)
Constructor Function. Init member variables.
VulkanObject Class. This class defines the basic behaves of VulkanObject. When we create an new Vulka...
This struct contains all Vulkan object in used global.
Definition VulkanUtils.h:74