@@ -37,15 +37,8 @@ const std::string MODEL_PATH = "models/viking_room.obj";
3737const std::string TEXTURE_PATH = " textures/viking_room.png" ;
3838constexpr int MAX_FRAMES_IN_FLIGHT = 2 ;
3939
40- const std::vector validationLayers = {
41- " VK_LAYER_KHRONOS_validation"
42- };
43-
44- #ifdef NDEBUG
45- constexpr bool enableValidationLayers = false ;
46- #else
47- constexpr bool enableValidationLayers = true ;
48- #endif
40+ // Validation layers are now managed by vulkanconfig instead of being hard-coded
41+ // See the Ecosystem Utilities chapter for details on using vulkanconfig
4942
5043// Application info structure to store feature support flags
5144struct AppInfo {
@@ -273,40 +266,56 @@ class HelloTriangleApplication {
273266 }
274267
275268 void createInstance () {
276- if (enableValidationLayers && !checkValidationLayerSupport ()) {
277- throw std::runtime_error (" validation layers requested, but not available!" );
278- }
269+ // Validation layers are now managed by vulkanconfig instead of being hard-coded
270+
271+ constexpr vk::ApplicationInfo appInfo{
272+ .pApplicationName = " Hello Triangle" ,
273+ .applicationVersion = VK_MAKE_VERSION ( 1 , 0 , 0 ),
274+ .pEngineName = " No Engine" ,
275+ .engineVersion = VK_MAKE_VERSION ( 1 , 0 , 0 ),
276+ .apiVersion = vk::ApiVersion14
277+ };
279278
280- constexpr vk::ApplicationInfo appInfo{ .pApplicationName = " Hello Triangle" ,
281- .applicationVersion = VK_MAKE_VERSION ( 1 , 0 , 0 ),
282- .pEngineName = " No Engine" ,
283- .engineVersion = VK_MAKE_VERSION ( 1 , 0 , 0 ),
284- .apiVersion = vk::ApiVersion14 };
285279 auto extensions = getRequiredExtensions ();
286- std::vector<char const *> enabledLayers;
287- if (enableValidationLayers) {
288- enabledLayers.assign (validationLayers.begin (), validationLayers.end ());
289- }
280+
290281 vk::InstanceCreateInfo createInfo{
291282 .pApplicationInfo = &appInfo,
292- .enabledLayerCount = static_cast <uint32_t >(enabledLayers.size ()),
293- .ppEnabledLayerNames = enabledLayers.data (),
294283 .enabledExtensionCount = static_cast <uint32_t >(extensions.size ()),
295- .ppEnabledExtensionNames = extensions.data () };
284+ .ppEnabledExtensionNames = extensions.data ()
285+ };
286+
296287 instance = vk::raii::Instance (context, createInfo);
297288 }
298289
299290 void setupDebugMessenger () {
300- if (!enableValidationLayers) return ;
291+ // Always set up the debug messenger
292+ // It will only be used if validation layers are enabled via vulkanconfig
293+
294+ vk::DebugUtilsMessageSeverityFlagsEXT severityFlags (
295+ vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
296+ vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
297+ vk::DebugUtilsMessageSeverityFlagBitsEXT::eError
298+ );
299+
300+ vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags (
301+ vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
302+ vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
303+ vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
304+ );
301305
302- vk::DebugUtilsMessageSeverityFlagsEXT severityFlags ( vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
303- vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags ( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
304306 vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{
305307 .messageSeverity = severityFlags,
306308 .messageType = messageTypeFlags,
307309 .pfnUserCallback = &debugCallback
308310 };
309- debugMessenger = instance.createDebugUtilsMessengerEXT (debugUtilsMessengerCreateInfoEXT);
311+
312+ try {
313+ debugMessenger = instance.createDebugUtilsMessengerEXT (debugUtilsMessengerCreateInfoEXT);
314+ } catch (vk::SystemError& err) {
315+ // If the debug utils extension is not available, this will fail
316+ // That's okay, it just means validation layers aren't enabled
317+ std::cout << " Debug messenger not available. Validation layers may not be enabled." << std::endl;
318+ }
310319 }
311320
312321 void createSurface () {
@@ -1377,9 +1386,9 @@ class HelloTriangleApplication {
13771386 vk::PipelineStageFlagBits::eTopOfPipe,
13781387 vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests,
13791388 vk::DependencyFlagBits::eByRegion,
1380- 0 , nullptr ,
1381- 0 , nullptr ,
1382- static_cast < uint32_t >( barriers. size ()), barriers. data ()
1389+ {} ,
1390+ {} ,
1391+ barriers
13831392 );
13841393 }
13851394
@@ -1474,9 +1483,9 @@ class HelloTriangleApplication {
14741483 vk::PipelineStageFlagBits::eColorAttachmentOutput,
14751484 vk::PipelineStageFlagBits::eBottomOfPipe,
14761485 vk::DependencyFlagBits::eByRegion,
1477- 0 , nullptr ,
1478- 0 , nullptr ,
1479- 1 , & barrier
1486+ {} ,
1487+ {} ,
1488+ { barrier }
14801489 );
14811490 }
14821491 } else {
@@ -1655,28 +1664,29 @@ class HelloTriangleApplication {
16551664 }
16561665
16571666 [[nodiscard]] std::vector<const char *> getRequiredExtensions () const {
1667+ // Get the required extensions from GLFW
16581668 uint32_t glfwExtensionCount = 0 ;
16591669 auto glfwExtensions = glfwGetRequiredInstanceExtensions (&glfwExtensionCount);
1670+ std::vector extensions (glfwExtensions, glfwExtensions + glfwExtensionCount);
16601671
1672+ // Check if the debug utils extension is available
16611673 std::vector<vk::ExtensionProperties> props = context.enumerateInstanceExtensionProperties ();
1662- if (const auto propsIterator = std::ranges::find_if (props, []( vk::ExtensionProperties const & ep ) { return strcmp ( ep.extensionName , vk::EXTDebugUtilsExtensionName ) == 0 ; } ); propsIterator == props.end () )
1663- {
1664- std::cout << " Something went very wrong, cannot find VK_EXT_debug_utils extension" << std::endl;
1665- exit ( 1 );
1666- }
1667- std::vector extensions (glfwExtensions, glfwExtensions + glfwExtensionCount);
1668- if (enableValidationLayers) {
1669- extensions.push_back (vk::EXTDebugUtilsExtensionName );
1674+ bool debugUtilsAvailable = std::ranges::any_of (props,
1675+ [](vk::ExtensionProperties const & ep) {
1676+ return strcmp (ep.extensionName , vk::EXTDebugUtilsExtensionName) == 0 ;
1677+ });
1678+
1679+ // Always include the debug utils extension if available
1680+ // This allows validation layers to be enabled via vulkanconfig
1681+ if (debugUtilsAvailable) {
1682+ extensions.push_back (vk::EXTDebugUtilsExtensionName);
1683+ } else {
1684+ std::cout << " VK_EXT_debug_utils extension not available. Validation layers may not work." << std::endl;
16701685 }
16711686
16721687 return extensions;
16731688 }
16741689
1675- [[nodiscard]] bool checkValidationLayerSupport () const {
1676- return (std::ranges::any_of (context.enumerateInstanceLayerProperties (),
1677- []( vk::LayerProperties const & lp ) { return ( strcmp ( " VK_LAYER_KHRONOS_validation" , lp.layerName ) == 0 ); } ) );
1678- }
1679-
16801690 static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback (vk::DebugUtilsMessageSeverityFlagBitsEXT severity, vk::DebugUtilsMessageTypeFlagsEXT type, const vk::DebugUtilsMessengerCallbackDataEXT* pCallbackData, void *) {
16811691 if (severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eError || severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) {
16821692 std::cerr << " validation layer: type " << to_string (type) << " msg: " << pCallbackData->pMessage << std::endl;
0 commit comments