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-
3928class HelloTriangleApplication {
4029public:
4130 void run () {
@@ -46,10 +35,11 @@ class HelloTriangleApplication {
4635 }
4736
4837private:
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
190139int 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