Skip to content

Commit ccb6d17

Browse files
committed
Refactor Vulkan setup instructions for clarity and consistency
Streamline formatting, clarify key setup steps, and consolidate redundant information in Vulkan development guide. Focus on improving readability while maintaining cross-platform support for Vulkan SDK, dependencies, and build tools like CMake and GLFW.
1 parent 6f39a73 commit ccb6d17

File tree

72 files changed

+12543
-24092
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+12543
-24092
lines changed

attachments/00_base_code.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#define GLFW_INCLUDE_VULKAN
1+
import vulkan_hpp;
22
#include <GLFW/glfw3.h>
33

44
#include <iostream>

attachments/01_instance_creation.cpp

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
#define GLFW_INCLUDE_VULKAN
2-
#include <GLFW/glfw3.h>
3-
41
#include <iostream>
52
#include <stdexcept>
63
#include <cstdlib>
4+
#include <memory>
5+
6+
import vulkan_hpp;
7+
#include <vulkan/vk_platform.h>
78

8-
const uint32_t WIDTH = 800;
9-
const uint32_t HEIGHT = 600;
9+
#define GLFW_INCLUDE_VULKAN // REQUIRED only for GLFW CreateWindowSurface.
10+
#include <GLFW/glfw3.h>
11+
12+
constexpr uint32_t WIDTH = 800;
13+
constexpr uint32_t HEIGHT = 600;
1014

1115
class HelloTriangleApplication {
1216
public:
@@ -18,9 +22,10 @@ class HelloTriangleApplication {
1822
}
1923

2024
private:
21-
GLFWwindow* window;
25+
GLFWwindow* window = nullptr;
2226

23-
VkInstance instance;
27+
vk::raii::Context context;
28+
std::unique_ptr<vk::raii::Instance> instance;
2429

2530
void initWindow() {
2631
glfwInit();
@@ -42,45 +47,23 @@ class HelloTriangleApplication {
4247
}
4348

4449
void cleanup() {
45-
vkDestroyInstance(instance, nullptr);
46-
4750
glfwDestroyWindow(window);
4851

4952
glfwTerminate();
5053
}
5154

5255
void createInstance() {
53-
VkApplicationInfo appInfo{};
54-
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
55-
appInfo.pApplicationName = "Hello Triangle";
56-
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
57-
appInfo.pEngineName = "No Engine";
58-
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
59-
appInfo.apiVersion = VK_API_VERSION_1_0;
60-
61-
VkInstanceCreateInfo createInfo{};
62-
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
63-
createInfo.pApplicationInfo = &appInfo;
64-
56+
constexpr auto appInfo = vk::ApplicationInfo("Hello Triangle", 1, "No Engine", 1, vk::ApiVersion14);
6557
uint32_t glfwExtensionCount = 0;
66-
const char** glfwExtensions;
67-
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
68-
69-
createInfo.enabledExtensionCount = glfwExtensionCount;
70-
createInfo.ppEnabledExtensionNames = glfwExtensions;
71-
72-
createInfo.enabledLayerCount = 0;
73-
74-
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
75-
throw std::runtime_error("failed to create instance!");
76-
}
58+
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
59+
vk::InstanceCreateInfo createInfo({}, &appInfo, {}, glfwExtensions);
60+
instance = std::make_unique<vk::raii::Instance>(context, createInfo);
7761
}
7862
};
7963

8064
int main() {
81-
HelloTriangleApplication app;
82-
8365
try {
66+
HelloTriangleApplication app;
8467
app.run();
8568
} catch (const std::exception& e) {
8669
std::cerr << e.what() << std::endl;

attachments/02_validation_layers.cpp

Lines changed: 43 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,30 @@
1-
#define GLFW_INCLUDE_VULKAN
2-
#include <GLFW/glfw3.h>
3-
41
#include <iostream>
52
#include <stdexcept>
63
#include <vector>
74
#include <cstring>
85
#include <cstdlib>
6+
#include <memory>
7+
#include <algorithm>
8+
9+
import vulkan_hpp;
10+
#include <vulkan/vk_platform.h>
11+
12+
#define GLFW_INCLUDE_VULKAN // REQUIRED only for GLFW CreateWindowSurface.
13+
#include <GLFW/glfw3.h>
914

10-
const uint32_t WIDTH = 800;
11-
const uint32_t HEIGHT = 600;
15+
constexpr uint32_t WIDTH = 800;
16+
constexpr uint32_t HEIGHT = 600;
1217

13-
const std::vector<const char*> validationLayers = {
18+
const std::vector validationLayers = {
1419
"VK_LAYER_KHRONOS_validation"
1520
};
1621

1722
#ifdef NDEBUG
18-
const bool enableValidationLayers = false;
23+
constexpr bool enableValidationLayers = false;
1924
#else
20-
const bool enableValidationLayers = true;
25+
constexpr bool enableValidationLayers = true;
2126
#endif
2227

23-
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) {
24-
auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
25-
if (func != nullptr) {
26-
return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
27-
} else {
28-
return VK_ERROR_EXTENSION_NOT_PRESENT;
29-
}
30-
}
31-
32-
void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) {
33-
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
34-
if (func != nullptr) {
35-
func(instance, debugMessenger, pAllocator);
36-
}
37-
}
38-
3928
class HelloTriangleApplication {
4029
public:
4130
void run() {
@@ -46,10 +35,11 @@ class HelloTriangleApplication {
4635
}
4736

4837
private:
49-
GLFWwindow* window;
38+
GLFWwindow* window = nullptr;
5039

51-
VkInstance instance;
52-
VkDebugUtilsMessengerEXT debugMessenger;
40+
vk::raii::Context context;
41+
std::unique_ptr<vk::raii::Instance> instance;
42+
std::unique_ptr<vk::raii::DebugUtilsMessengerEXT> debugMessenger;
5343

5444
void initWindow() {
5545
glfwInit();
@@ -72,12 +62,6 @@ class HelloTriangleApplication {
7262
}
7363

7464
void cleanup() {
75-
if (enableValidationLayers) {
76-
DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
77-
}
78-
79-
vkDestroyInstance(instance, nullptr);
80-
8165
glfwDestroyWindow(window);
8266

8367
glfwTerminate();
@@ -88,109 +72,60 @@ class HelloTriangleApplication {
8872
throw std::runtime_error("validation layers requested, but not available!");
8973
}
9074

91-
VkApplicationInfo appInfo{};
92-
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
93-
appInfo.pApplicationName = "Hello Triangle";
94-
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
95-
appInfo.pEngineName = "No Engine";
96-
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
97-
appInfo.apiVersion = VK_API_VERSION_1_0;
98-
99-
VkInstanceCreateInfo createInfo{};
100-
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
101-
createInfo.pApplicationInfo = &appInfo;
102-
75+
constexpr auto appInfo = vk::ApplicationInfo("Hello Triangle", 1, "No Engine", 1, vk::ApiVersion14);
10376
auto extensions = getRequiredExtensions();
104-
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
105-
createInfo.ppEnabledExtensionNames = extensions.data();
106-
107-
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
77+
std::vector<char const *> enabledLayers;
10878
if (enableValidationLayers) {
109-
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
110-
createInfo.ppEnabledLayerNames = validationLayers.data();
111-
112-
populateDebugMessengerCreateInfo(debugCreateInfo);
113-
createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo;
114-
} else {
115-
createInfo.enabledLayerCount = 0;
116-
117-
createInfo.pNext = nullptr;
118-
}
119-
120-
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
121-
throw std::runtime_error("failed to create instance!");
79+
enabledLayers.assign(validationLayers.begin(), validationLayers.end());
12280
}
123-
}
124-
125-
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) {
126-
createInfo = {};
127-
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
128-
createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
129-
createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
130-
createInfo.pfnUserCallback = debugCallback;
81+
vk::InstanceCreateInfo createInfo({}, &appInfo, enabledLayers.size(), enabledLayers.data(), extensions.size(), extensions.data());
82+
instance = std::make_unique<vk::raii::Instance>(context, createInfo);
13183
}
13284

13385
void setupDebugMessenger() {
13486
if (!enableValidationLayers) return;
13587

136-
VkDebugUtilsMessengerCreateInfoEXT createInfo;
137-
populateDebugMessengerCreateInfo(createInfo);
138-
139-
if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
140-
throw std::runtime_error("failed to set up debug messenger!");
141-
}
88+
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
89+
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
90+
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT({}, severityFlags, messageTypeFlags, &debugCallback);
91+
debugMessenger = std::make_unique<vk::raii::DebugUtilsMessengerEXT>( *instance, debugUtilsMessengerCreateInfoEXT );
14292
}
14393

14494
std::vector<const char*> getRequiredExtensions() {
14595
uint32_t glfwExtensionCount = 0;
146-
const char** glfwExtensions;
147-
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
148-
149-
std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
96+
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
15097

98+
std::vector<vk::ExtensionProperties> props = context.enumerateInstanceExtensionProperties();
99+
if (const auto propsIterator = std::ranges::find_if(props, []( vk::ExtensionProperties const & ep ) { return strcmp( ep.extensionName, vk::EXTDebugUtilsExtensionName ) == 0; } ); propsIterator == props.end() )
100+
{
101+
std::cout << "Something went very wrong, cannot find VK_EXT_debug_utils extension" << std::endl;
102+
exit( 1 );
103+
}
104+
std::vector extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
151105
if (enableValidationLayers) {
152-
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
106+
extensions.push_back(vk::EXTDebugUtilsExtensionName );
153107
}
154108

155109
return extensions;
156110
}
157111

158112
bool checkValidationLayerSupport() {
159-
uint32_t layerCount;
160-
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
161-
162-
std::vector<VkLayerProperties> availableLayers(layerCount);
163-
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
164-
165-
for (const char* layerName : validationLayers) {
166-
bool layerFound = false;
167-
168-
for (const auto& layerProperties : availableLayers) {
169-
if (strcmp(layerName, layerProperties.layerName) == 0) {
170-
layerFound = true;
171-
break;
172-
}
173-
}
174-
175-
if (!layerFound) {
176-
return false;
177-
}
178-
}
179-
180-
return true;
113+
return (std::ranges::any_of(context.enumerateInstanceLayerProperties(),
114+
[]( vk::LayerProperties const & lp ) { return ( strcmp( "VK_LAYER_KHRONOS_validation", lp.layerName ) == 0 ); } ) );
181115
}
182116

183-
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) {
184-
std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl;
117+
static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback(vk::DebugUtilsMessageSeverityFlagBitsEXT severity, vk::DebugUtilsMessageTypeFlagsEXT type, const vk::DebugUtilsMessengerCallbackDataEXT* pCallbackData, void*) {
118+
if (severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eError || severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) {
119+
std::cerr << "validation layer: type " << to_string(type) << " msg: " << pCallbackData->pMessage << std::endl;
120+
}
185121

186-
return VK_FALSE;
122+
return vk::False;
187123
}
188124
};
189125

190126
int main() {
191-
HelloTriangleApplication app;
192-
193127
try {
128+
HelloTriangleApplication app;
194129
app.run();
195130
} catch (const std::exception& e) {
196131
std::cerr << e.what() << std::endl;

0 commit comments

Comments
 (0)