1+ #include < iostream>
2+ #include < print>
3+ #include < set>
4+ #include < stdexcept>
5+ #include < optional>
6+
17#include < vulkan/vulkan.hpp>
28#include < vulkan/vulkan_raii.hpp>
39#include < GLFW/glfw3.h>
410
5- #include < iostream>
6- #include < vector>
7- #include < array>
8- #include < set>
9- #include < memory>
10- #include < optional>
11- #include < stdexcept>
11+
12+
13+ constexpr uint32_t WIDTH = 800 ;
14+ constexpr uint32_t HEIGHT = 600 ;
15+
16+ constexpr std::array<const char *,1 > REQUIRED_LAYERS {
17+ " VK_LAYER_KHRONOS_validation"
18+ };
19+
20+ #ifdef NDEBUG
21+ constexpr bool ENABLE_VALIDATION_LAYER = false ;
22+ #else
23+ constexpr bool ENABLE_VALIDATION_LAYER = true ;
24+ #endif
25+
26+ struct QueueFamilyIndices {
27+ std::optional<uint32_t > graphicsFamily;
28+
29+ bool isComplete () const {
30+ return graphicsFamily.has_value ();
31+ }
32+ };
1233
1334class HelloTriangleApplication {
1435public:
@@ -20,33 +41,17 @@ class HelloTriangleApplication {
2041 }
2142
2243private:
23- // ///////////////////////////////////////////////////////////////
24- // / static values
25- static constexpr uint32_t WIDTH = 800 ;
26- static constexpr uint32_t HEIGHT = 600 ;
27-
28- inline static const std::vector<const char *> validationLayers {
29- " VK_LAYER_KHRONOS_validation"
30- };
31-
32- #ifdef NDEBUG
33- static constexpr bool enableValidationLayers = false ;
34- #else
35- static constexpr bool enableValidationLayers = true ;
36- #endif
37- // ///////////////////////////////////////////////////////////////
38-
39- // ///////////////////////////////////////////////////////////////
44+ // ///////////////////////////////////////////////////////////
4045 // / class member
4146 GLFWwindow* m_window{ nullptr };
4247 vk::raii::Context m_context;
4348 vk::raii::Instance m_instance{ nullptr };
4449 vk::raii::DebugUtilsMessengerEXT m_debugMessenger{ nullptr };
4550 vk::raii::PhysicalDevice m_physicalDevice{ nullptr };
46- // ///////////////////////////////////////////////////////////////
51+ // ///////////////////////////////////////////////////////////
4752
48- // ///////////////////////////////////////////////////////////////
49- // / run()
53+ // ///////////////////////////////////////////////////////////
54+ // / run functions
5055 void initWindow () {
5156 glfwInit ();
5257
@@ -59,7 +64,7 @@ class HelloTriangleApplication {
5964 void initVulkan () {
6065 createInstance ();
6166 setupDebugMessenger ();
62- pickPhysicalDevice ();
67+ selectPhysicalDevice ();
6368 }
6469
6570 void mainLoop () {
@@ -72,127 +77,123 @@ class HelloTriangleApplication {
7277 glfwDestroyWindow ( m_window );
7378 glfwTerminate ();
7479 }
75- // ///////////////////////////////////////////////////////////////
80+ // ///////////////////////////////////////////////////////////
7681
77- // ///////////////////////////////////////////////////////////////
78- // / instance creation
79- std::vector<const char *> getRequiredExtensions () {
82+ // ///////////////////////////////////////////////////////////
83+ // / create instance and validation layers
84+ static VKAPI_ATTR uint32_t VKAPI_CALL debugMessageFunc (
85+ vk::DebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
86+ vk::DebugUtilsMessageTypeFlagsEXT messageTypes,
87+ vk::DebugUtilsMessengerCallbackDataEXT const * pCallbackData,
88+ void * pUserData
89+ ) {
90+ std::println (std::cerr, " validation layer: {}" , pCallbackData->pMessage );
91+ return false ;
92+ }
93+ static constexpr vk::DebugUtilsMessengerCreateInfoEXT populateDebugMessengerCreateInfo () {
94+ constexpr vk::DebugUtilsMessageSeverityFlagsEXT severityFlags (
95+ vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
96+ vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
97+ vk::DebugUtilsMessageSeverityFlagBitsEXT::eError
98+ );
99+ constexpr vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags (
100+ vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
101+ vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
102+ vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
103+ );
104+ return { {}, severityFlags, messageTypeFlags, &debugMessageFunc };
105+ }
106+ void setupDebugMessenger () {
107+ if constexpr (!ENABLE_VALIDATION_LAYER) return ;
108+ constexpr auto createInfo = populateDebugMessengerCreateInfo ();
109+ m_debugMessenger = m_instance.createDebugUtilsMessengerEXT ( createInfo );
110+ }
111+ static std::vector<const char *> getRequiredExtensions () {
80112 uint32_t glfwExtensionCount = 0 ;
81- const char ** glfwExtensions;
82- glfwExtensions = glfwGetRequiredInstanceExtensions (&glfwExtensionCount);
83-
84- std::vector<const char *> extensions (glfwExtensions, glfwExtensions + glfwExtensionCount);
85-
86- if (enableValidationLayers) {
113+ const char **glfwExtensions = glfwGetRequiredInstanceExtensions (&glfwExtensionCount);
114+ std::vector<const char *> extensions (glfwExtensions, glfwExtensions + glfwExtensionCount);
115+ extensions.emplace_back (vk::KHRPortabilityEnumerationExtensionName);
116+ if constexpr (ENABLE_VALIDATION_LAYER) {
87117 extensions.emplace_back ( vk::EXTDebugUtilsExtensionName );
88118 }
89- extensions.emplace_back ( vk::KHRPortabilityEnumerationExtensionName );
90-
91119 return extensions;
92120 }
93- void createInstance (){
94- if (enableValidationLayers && !checkValidationLayerSupport ()) {
95- throw std::runtime_error (" validation layers requested, but not available!" );
121+ bool checkValidationLayerSupport () const {
122+ const auto layers = m_context.enumerateInstanceLayerProperties ();
123+ std::set<std::string> requiredLayers (REQUIRED_LAYERS.begin (), REQUIRED_LAYERS.end ());
124+ for (const auto &layer: layers) {
125+ requiredLayers.erase (layer.layerName );
96126 }
127+ return requiredLayers.empty ();
128+ }
97129
98- vk::ApplicationInfo applicationInfo (
99- " Hello Triangle" , // pApplicationName
130+ void createInstance () {
131+ if constexpr (ENABLE_VALIDATION_LAYER) {
132+ if (!checkValidationLayerSupport ()) throw std::runtime_error (
133+ " validation layers requested, but not available!" );
134+ }
135+
136+ constexpr vk::ApplicationInfo applicationInfo (
137+ " Hello Vulkan" , // pApplicationName
100138 1 , // applicationVersion
101139 " No Engine" , // pEngineName
102140 1 , // engineVersion
103141 vk::makeApiVersion (0 , 1 , 4 , 0 ) // apiVersion
104142 );
105-
106- vk::InstanceCreateInfo createInfo (
143+ vk::InstanceCreateInfo createInfo (
107144 {}, // vk::InstanceCreateFlags
108145 &applicationInfo // vk::ApplicationInfo*
109146 );
110147
111148 std::vector<const char *> requiredExtensions = getRequiredExtensions ();
112- // special setter
113149 createInfo.setPEnabledExtensionNames ( requiredExtensions );
114150 createInfo.flags |= vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR;
115151
116- // vk::DebugUtilsMessengerCreateInfoEXT
117- auto debugMessengerCreateInfo = populateDebugMessengerCreateInfo ();
118- if (enableValidationLayers) {
119- createInfo.setPEnabledLayerNames ( validationLayers );
120- createInfo.pNext = &debugMessengerCreateInfo;
121- }
122-
123- auto extensions = m_context.enumerateInstanceExtensionProperties ();
152+ // std::vector<vk::ExtensionProperties>
153+ const auto extensions = m_context.enumerateInstanceExtensionProperties ();
124154 std::cout << " available extensions:\n " ;
125-
126155 for (const auto & extension : extensions) {
127- std::cout << ' \t ' << extension.extensionName << std::endl;
156+ std::println (" \t {}" , std::string_view (extension.extensionName ));
157+ }
158+
159+ constexpr auto debugMessengerCreateInfo = populateDebugMessengerCreateInfo ();
160+ if constexpr (ENABLE_VALIDATION_LAYER) {
161+ createInfo.setPEnabledLayerNames ( REQUIRED_LAYERS );
162+ createInfo.pNext = &debugMessengerCreateInfo ;
128163 }
129164
130165 m_instance = m_context.createInstance ( createInfo );
131166 }
132- // ///////////////////////////////////////////////////////////////
167+ // ///////////////////////////////////////////////////////////
133168
134- // ///////////////////////////////////////////////////////////////
135- // / validation layer
136- static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageFunc (
137- vk::DebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
138- vk::DebugUtilsMessageTypeFlagsEXT messageTypes,
139- vk::DebugUtilsMessengerCallbackDataEXT const * pCallbackData,
140- void * pUserData ) {
141169
142- std::cerr << " validation layer: " << pCallbackData->pMessage << std::endl;
170+ // ///////////////////////////////////////////////////////////
171+ // / device and queue
172+ QueueFamilyIndices findQueueFamilies (const vk::raii::PhysicalDevice& physicalDevice) const {
173+ QueueFamilyIndices indices;
174+ // std::vector<vk::QueueFamilyProperties>
175+ const auto queueFamilies = physicalDevice.getQueueFamilyProperties ();
176+ for (int i = 0 ; const auto & queueFamily : queueFamilies) {
177+ if (queueFamily.queueFlags & vk::QueueFlagBits::eGraphics) {
178+ indices.graphicsFamily = i;
179+ }
180+ if (indices.isComplete ()) break ;
143181
144- return false ;
145- }
146- bool checkValidationLayerSupport () {
147- auto layers = m_context.enumerateInstanceLayerProperties ();
148- std::set<std::string> t_requiredLayers ( validationLayers.begin (), validationLayers.end () );
149- for (const auto & layer : layers) {
150- t_requiredLayers.erase ( layer.layerName );
182+ ++i;
151183 }
152- return t_requiredLayers.empty ();
153- }
154- vk::DebugUtilsMessengerCreateInfoEXT populateDebugMessengerCreateInfo () {
155- vk::DebugUtilsMessageSeverityFlagsEXT severityFlags (
156- vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
157- vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
158- vk::DebugUtilsMessageSeverityFlagBitsEXT::eError
159- );
160- vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags (
161- vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
162- vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
163- vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
164- );
165- return vk::DebugUtilsMessengerCreateInfoEXT ( {}, severityFlags, messageTypeFlags, &debugMessageFunc );
166- }
167- void setupDebugMessenger (){
168- if (!enableValidationLayers) return ;
169-
170- auto createInfo = populateDebugMessengerCreateInfo ();
171- m_debugMessenger = m_instance.createDebugUtilsMessengerEXT ( createInfo );
184+ return indices;
172185 }
173- // ///////////////////////////////////////////////////////////////
174-
175- // ///////////////////////////////////////////////////////////////
176- // / physical device
177- struct QueueFamilyIndices {
178- std::optional<uint32_t > graphicsFamily;
179-
180- bool isComplete () {
181- return graphicsFamily.has_value ();
182- }
183- };
184- bool isDeviceSuitable (const vk::raii::PhysicalDevice& physicalDevice) {
185- QueueFamilyIndices indices = findQueueFamilies (physicalDevice);
186+ bool isDeviceSuitable (const vk::raii::PhysicalDevice& physicalDevice) const {
187+ const auto indices = findQueueFamilies (physicalDevice);
186188
187189 return indices.isComplete ();
188190 }
189- void pickPhysicalDevice () {
191+ void selectPhysicalDevice () {
190192 // std::vector<vk::raii::PhysicalDevice>
191- auto physicalDevices = m_instance.enumeratePhysicalDevices ();
193+ const auto physicalDevices = m_instance.enumeratePhysicalDevices ();
192194 if (physicalDevices.empty ()){
193195 throw std::runtime_error (" failed to find GPUs with Vulkan support!" );
194196 }
195-
196197 for (const auto & it : physicalDevices) {
197198 if (isDeviceSuitable (it)) {
198199 m_physicalDevice = it;
@@ -203,38 +204,18 @@ class HelloTriangleApplication {
203204 throw std::runtime_error (" failed to find a suitable GPU!" );
204205 }
205206 }
206- QueueFamilyIndices findQueueFamilies (const vk::raii::PhysicalDevice& physicalDevice) {
207- QueueFamilyIndices indices;
208-
209- // std::vector<vk::QueueFamilyProperties>
210- auto queueFamilies = physicalDevice.getQueueFamilyProperties ();
211- for (int i = 0 ; const auto & queueFamily : queueFamilies) {
212- if (queueFamily.queueFlags & vk::QueueFlagBits::eGraphics) {
213- indices.graphicsFamily = i;
214- }
215- if (indices.isComplete ()) {
216- break ;
217- }
218-
219- ++i;
220- }
221-
222- return indices;
223- }
224- // ///////////////////////////////////////////////////////////////
207+ // ///////////////////////////////////////////////////////////
225208};
226209
227210int main () {
228- HelloTriangleApplication app;
229-
230211 try {
212+ HelloTriangleApplication app;
231213 app.run ();
232- } catch (const vk::SystemError & err ){
214+ } catch (const vk::SystemError& err ) {
233215 // use err.code() to check err type
234- std::cout << " vk::SystemError: " << err.what () << std::endl;
235- } catch (const std::exception & err ){
236- std::cout << " std::exception: " << err.what () << std::endl;
216+ std::println ( std::cerr, " vk::SystemError - code: {} " ,err.code ().message ());
217+ std::println ( std::cerr, " vk::SystemError - what: {}" ,err.what ());
218+ } catch (const std::exception& err ) {
219+ std::println ( std::cerr, " std::exception: {}" , err.what ());
237220 }
238-
239- return 0 ;
240- }
221+ }
0 commit comments