Skip to content

Commit 40da256

Browse files
Merge pull request #61 from gpx1000/rewrite
This is a new version of the tutorial using RAII and SLang
2 parents 9520fc2 + 9782f9f commit 40da256

File tree

86 files changed

+17047
-27068
lines changed

Some content is hidden

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

86 files changed

+17047
-27068
lines changed

attachments/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

attachments/00_base_code.cpp

Lines changed: 3 additions & 3 deletions
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>
@@ -18,7 +18,7 @@ class HelloTriangleApplication {
1818
}
1919

2020
private:
21-
GLFWwindow* window;
21+
GLFWwindow* window = nullptr;
2222

2323
void initWindow() {
2424
glfwInit();
@@ -47,7 +47,7 @@ class HelloTriangleApplication {
4747
};
4848

4949
int main() {
50-
HelloTriangleApplication app;
50+
HelloTriangleApplication app{};
5151

5252
try {
5353
app.run();

attachments/01_instance_creation.cpp

Lines changed: 23 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+
vk::raii::Instance instance = nullptr;
2429

2530
void initWindow() {
2631
glfwInit();
@@ -42,45 +47,29 @@ 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 vk::ApplicationInfo appInfo{ .pApplicationName = "Hello Triangle",
57+
.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 ),
58+
.pEngineName = "No Engine",
59+
.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ),
60+
.apiVersion = vk::ApiVersion14 };
6561
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-
}
62+
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
63+
vk::InstanceCreateInfo createInfo{
64+
.pApplicationInfo = &appInfo,
65+
.ppEnabledLayerNames = glfwExtensions};
66+
instance = vk::raii::Instance(context, createInfo);
7767
}
7868
};
7969

8070
int main() {
81-
HelloTriangleApplication app;
82-
8371
try {
72+
HelloTriangleApplication app;
8473
app.run();
8574
} catch (const std::exception& e) {
8675
std::cerr << e.what() << std::endl;

attachments/02_validation_layers.cpp

Lines changed: 56 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+
vk::raii::Instance instance = nullptr;
42+
vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
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,73 @@ 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 vk::ApplicationInfo appInfo{ .pApplicationName = "Hello Triangle",
76+
.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 ),
77+
.pEngineName = "No Engine",
78+
.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ),
79+
.apiVersion = vk::ApiVersion14 };
10380
auto extensions = getRequiredExtensions();
104-
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
105-
createInfo.ppEnabledExtensionNames = extensions.data();
106-
107-
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
81+
std::vector<char const *> enabledLayers;
10882
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!");
83+
enabledLayers.assign(validationLayers.begin(), validationLayers.end());
12284
}
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;
85+
vk::InstanceCreateInfo createInfo{
86+
.pApplicationInfo = &appInfo,
87+
.enabledLayerCount = static_cast<uint32_t>(enabledLayers.size()),
88+
.ppEnabledLayerNames = enabledLayers.data(),
89+
.enabledExtensionCount = static_cast<uint32_t>(extensions.size()),
90+
.ppEnabledExtensionNames = extensions.data() };
91+
instance = vk::raii::Instance(context, createInfo);
13192
}
13293

13394
void setupDebugMessenger() {
13495
if (!enableValidationLayers) return;
13596

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-
}
97+
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
98+
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
99+
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{
100+
.messageSeverity = severityFlags,
101+
.messageType = messageTypeFlags,
102+
.pfnUserCallback = &debugCallback
103+
};
104+
debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT);
142105
}
143106

144107
std::vector<const char*> getRequiredExtensions() {
145108
uint32_t glfwExtensionCount = 0;
146-
const char** glfwExtensions;
147-
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
148-
149-
std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
109+
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
150110

111+
std::vector<vk::ExtensionProperties> props = context.enumerateInstanceExtensionProperties();
112+
if (const auto propsIterator = std::ranges::find_if(props, []( vk::ExtensionProperties const & ep ) { return strcmp( ep.extensionName, vk::EXTDebugUtilsExtensionName ) == 0; } ); propsIterator == props.end() )
113+
{
114+
std::cout << "Something went very wrong, cannot find VK_EXT_debug_utils extension" << std::endl;
115+
exit( 1 );
116+
}
117+
std::vector extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
151118
if (enableValidationLayers) {
152-
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
119+
extensions.push_back(vk::EXTDebugUtilsExtensionName );
153120
}
154121

155122
return extensions;
156123
}
157124

158125
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;
126+
return (std::ranges::any_of(context.enumerateInstanceLayerProperties(),
127+
[]( vk::LayerProperties const & lp ) { return ( strcmp( "VK_LAYER_KHRONOS_validation", lp.layerName ) == 0 ); } ) );
181128
}
182129

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;
130+
static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback(vk::DebugUtilsMessageSeverityFlagBitsEXT severity, vk::DebugUtilsMessageTypeFlagsEXT type, const vk::DebugUtilsMessengerCallbackDataEXT* pCallbackData, void*) {
131+
if (severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eError || severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) {
132+
std::cerr << "validation layer: type " << to_string(type) << " msg: " << pCallbackData->pMessage << std::endl;
133+
}
185134

186-
return VK_FALSE;
135+
return vk::False;
187136
}
188137
};
189138

190139
int main() {
191-
HelloTriangleApplication app;
192-
193140
try {
141+
HelloTriangleApplication app;
194142
app.run();
195143
} catch (const std::exception& e) {
196144
std::cerr << e.what() << std::endl;

0 commit comments

Comments
 (0)