From 3a3cace1302ea724340e78c514b003e611c372a8 Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Wed, 18 Feb 2026 14:12:45 +0100 Subject: [PATCH 1/2] Adjust docu and source of 03_physical_device_selection --- attachments/03_physical_device_selection.cpp | 79 +++---- attachments/04_logical_device.cpp | 79 +++---- attachments/05_window_surface.cpp | 79 +++---- attachments/06_swap_chain_creation.cpp | 79 +++---- attachments/07_image_views.cpp | 79 +++---- attachments/08_graphics_pipeline.cpp | 79 +++---- attachments/09_shader_modules.cpp | 85 ++++---- attachments/10_fixed_functions.cpp | 85 ++++---- attachments/12_graphics_pipeline_complete.cpp | 85 ++++---- attachments/14_command_buffers.cpp | 71 +++---- attachments/15_hello_triangle.cpp | 87 ++++---- attachments/16_frames_in_flight.cpp | 87 ++++---- attachments/17_swap_chain_recreation.cpp | 87 ++++---- attachments/19_vertex_buffer.cpp | 82 +++---- attachments/20_staging_buffer.cpp | 82 +++---- attachments/21_index_buffer.cpp | 82 +++---- attachments/22_descriptor_layout.cpp | 82 +++---- attachments/23_descriptor_sets.cpp | 82 +++---- attachments/24_texture_image.cpp | 82 +++---- attachments/25_sampler.cpp | 82 +++---- attachments/26_texture_mapping.cpp | 82 +++---- attachments/27_depth_buffering.cpp | 82 +++---- attachments/28_model_loading.cpp | 82 +++---- attachments/29_mipmapping.cpp | 82 +++---- attachments/30_multisampling.cpp | 82 +++---- attachments/31_compute_shader.cpp | 91 ++++---- attachments/32_ecosystem_utilities.cpp | 67 +++--- attachments/33_vulkan_profiles.cpp | 82 +++---- attachments/34_android.cpp | 87 ++++---- attachments/35_gltf_ktx.cpp | 153 +++++++------ attachments/36_multiple_objects.cpp | 153 +++++++------ attachments/37_multithreading.cpp | 76 ++++--- attachments/38_ray_tracing.cpp | 105 ++++----- ...3_Physical_devices_and_queue_families.adoc | 201 +++++++++++------- 34 files changed, 1594 insertions(+), 1466 deletions(-) diff --git a/attachments/03_physical_device_selection.cpp b/attachments/03_physical_device_selection.cpp index 6cb02c24..67366b76 100644 --- a/attachments/03_physical_device_selection.cpp +++ b/attachments/03_physical_device_selection.cpp @@ -149,44 +149,47 @@ class HelloTriangleApplication debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } std::vector getRequiredInstanceExtensions() { diff --git a/attachments/04_logical_device.cpp b/attachments/04_logical_device.cpp index e4762c30..1e649537 100644 --- a/attachments/04_logical_device.cpp +++ b/attachments/04_logical_device.cpp @@ -154,44 +154,47 @@ class HelloTriangleApplication debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/05_window_surface.cpp b/attachments/05_window_surface.cpp index e78f4293..b237c77b 100644 --- a/attachments/05_window_surface.cpp +++ b/attachments/05_window_surface.cpp @@ -162,44 +162,47 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/06_swap_chain_creation.cpp b/attachments/06_swap_chain_creation.cpp index 12a7cfbe..65d38d55 100644 --- a/attachments/06_swap_chain_creation.cpp +++ b/attachments/06_swap_chain_creation.cpp @@ -170,44 +170,47 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/07_image_views.cpp b/attachments/07_image_views.cpp index ae4c09ff..3b67a99d 100644 --- a/attachments/07_image_views.cpp +++ b/attachments/07_image_views.cpp @@ -171,44 +171,47 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/08_graphics_pipeline.cpp b/attachments/08_graphics_pipeline.cpp index 99aedff9..b35c5d7b 100644 --- a/attachments/08_graphics_pipeline.cpp +++ b/attachments/08_graphics_pipeline.cpp @@ -172,44 +172,47 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/09_shader_modules.cpp b/attachments/09_shader_modules.cpp index e17cb68d..d61d14b3 100644 --- a/attachments/09_shader_modules.cpp +++ b/attachments/09_shader_modules.cpp @@ -173,48 +173,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/10_fixed_functions.cpp b/attachments/10_fixed_functions.cpp index 9cd7112a..8d1b1417 100644 --- a/attachments/10_fixed_functions.cpp +++ b/attachments/10_fixed_functions.cpp @@ -175,48 +175,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/12_graphics_pipeline_complete.cpp b/attachments/12_graphics_pipeline_complete.cpp index 69ce5ef2..a3c1056a 100644 --- a/attachments/12_graphics_pipeline_complete.cpp +++ b/attachments/12_graphics_pipeline_complete.cpp @@ -176,48 +176,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/14_command_buffers.cpp b/attachments/14_command_buffers.cpp index db08aa36..7a90e90a 100644 --- a/attachments/14_command_buffers.cpp +++ b/attachments/14_command_buffers.cpp @@ -181,47 +181,46 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } + bool isDeviceSuitable(vk::raii::PhysicalDevice const &physicalDevice) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of(requiredDeviceExtension, + [&availableDeviceExtensions](auto const &requiredDeviceExtension) { + return std::ranges::any_of(availableDeviceExtensions, + [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); + }); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + void pickPhysicalDevice() { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if(physicalDevices, [&](auto const &physicalDevice) { return isDeviceSuitable(physicalDevice); }); + if (devIter == physicalDevices.end()) { throw std::runtime_error("failed to find a suitable GPU!"); } + physicalDevice = *devIter; } void createLogicalDevice() diff --git a/attachments/15_hello_triangle.cpp b/attachments/15_hello_triangle.cpp index ceeb8354..59b5f7a8 100644 --- a/attachments/15_hello_triangle.cpp +++ b/attachments/15_hello_triangle.cpp @@ -189,49 +189,50 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().synchronization2 && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().synchronization2 && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/16_frames_in_flight.cpp b/attachments/16_frames_in_flight.cpp index a25afc8f..08805d38 100644 --- a/attachments/16_frames_in_flight.cpp +++ b/attachments/16_frames_in_flight.cpp @@ -192,49 +192,50 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().synchronization2 && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().synchronization2 && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/17_swap_chain_recreation.cpp b/attachments/17_swap_chain_recreation.cpp index 4fd1181a..9f53abf7 100644 --- a/attachments/17_swap_chain_recreation.cpp +++ b/attachments/17_swap_chain_recreation.cpp @@ -225,49 +225,50 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().synchronization2 && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().synchronization2 && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/19_vertex_buffer.cpp b/attachments/19_vertex_buffer.cpp index 3f47a11c..ac17551b 100644 --- a/attachments/19_vertex_buffer.cpp +++ b/attachments/19_vertex_buffer.cpp @@ -254,45 +254,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/20_staging_buffer.cpp b/attachments/20_staging_buffer.cpp index 13b57d47..982e1fc2 100644 --- a/attachments/20_staging_buffer.cpp +++ b/attachments/20_staging_buffer.cpp @@ -254,45 +254,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/21_index_buffer.cpp b/attachments/21_index_buffer.cpp index 1c0255c0..a1ce7bef 100644 --- a/attachments/21_index_buffer.cpp +++ b/attachments/21_index_buffer.cpp @@ -261,45 +261,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/22_descriptor_layout.cpp b/attachments/22_descriptor_layout.cpp index f2e6789b..9f3e0a9c 100644 --- a/attachments/22_descriptor_layout.cpp +++ b/attachments/22_descriptor_layout.cpp @@ -279,45 +279,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/23_descriptor_sets.cpp b/attachments/23_descriptor_sets.cpp index bb2f5cef..653cd454 100644 --- a/attachments/23_descriptor_sets.cpp +++ b/attachments/23_descriptor_sets.cpp @@ -284,45 +284,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/24_texture_image.cpp b/attachments/24_texture_image.cpp index f22f1e24..55687d2f 100644 --- a/attachments/24_texture_image.cpp +++ b/attachments/24_texture_image.cpp @@ -291,45 +291,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().shaderDrawParameters && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().shaderDrawParameters && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/25_sampler.cpp b/attachments/25_sampler.cpp index a47e54da..44e7a1a4 100644 --- a/attachments/25_sampler.cpp +++ b/attachments/25_sampler.cpp @@ -295,45 +295,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/26_texture_mapping.cpp b/attachments/26_texture_mapping.cpp index 2e40aff0..2d6fb045 100644 --- a/attachments/26_texture_mapping.cpp +++ b/attachments/26_texture_mapping.cpp @@ -297,45 +297,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/27_depth_buffering.cpp b/attachments/27_depth_buffering.cpp index 938420fe..2a1c7aae 100644 --- a/attachments/27_depth_buffering.cpp +++ b/attachments/27_depth_buffering.cpp @@ -312,45 +312,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/28_model_loading.cpp b/attachments/28_model_loading.cpp index 34813cf1..9e1543f3 100644 --- a/attachments/28_model_loading.cpp +++ b/attachments/28_model_loading.cpp @@ -319,45 +319,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/29_mipmapping.cpp b/attachments/29_mipmapping.cpp index b2175f61..5618bceb 100644 --- a/attachments/29_mipmapping.cpp +++ b/attachments/29_mipmapping.cpp @@ -319,45 +319,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/30_multisampling.cpp b/attachments/30_multisampling.cpp index 63055ad1..8b5812ad 100644 --- a/attachments/30_multisampling.cpp +++ b/attachments/30_multisampling.cpp @@ -328,45 +328,49 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/31_compute_shader.cpp b/attachments/31_compute_shader.cpp index 5466a293..f6513842 100644 --- a/attachments/31_compute_shader.cpp +++ b/attachments/31_compute_shader.cpp @@ -293,51 +293,52 @@ class ComputeShaderApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState && - features.template get().timelineSemaphore; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } - - void createLogicalDevice() + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState && + features.template get().timelineSemaphore; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } + +void createLogicalDevice() { std::vector queueFamilyProperties = physicalDevice.getQueueFamilyProperties(); diff --git a/attachments/32_ecosystem_utilities.cpp b/attachments/32_ecosystem_utilities.cpp index fae9be01..8538f50a 100644 --- a/attachments/32_ecosystem_utilities.cpp +++ b/attachments/32_ecosystem_utilities.cpp @@ -348,38 +348,41 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - return supportsGraphics && supportsAllRequiredExtensions; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - msaaSamples = getMaxUsableSampleCount(); - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + msaaSamples = getMaxUsableSampleCount(); + } void detectFeatureSupport() { diff --git a/attachments/33_vulkan_profiles.cpp b/attachments/33_vulkan_profiles.cpp index 4f95486d..cd5340e0 100644 --- a/attachments/33_vulkan_profiles.cpp +++ b/attachments/33_vulkan_profiles.cpp @@ -356,46 +356,48 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - return supportsGraphics && supportsAllRequiredExtensions; - }); - - if (devIter != devices.end()) - { - physicalDevice = *devIter; - msaaSamples = getMaxUsableSampleCount(); - - // Print device information - vk::PhysicalDeviceProperties deviceProperties = physicalDevice.getProperties(); - std::cout << "Selected GPU: " << deviceProperties.deviceName << std::endl; - std::cout << "API Version: " << VK_VERSION_MAJOR(deviceProperties.apiVersion) << "." - << VK_VERSION_MINOR(deviceProperties.apiVersion) << "." - << VK_VERSION_PATCH(deviceProperties.apiVersion) << std::endl; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + msaaSamples = getMaxUsableSampleCount(); + + // Print device information + vk::PhysicalDeviceProperties deviceProperties = physicalDevice.getProperties(); + std::cout << "Selected GPU: " << deviceProperties.deviceName << std::endl; + std::cout << "API Version: " << VK_VERSION_MAJOR(deviceProperties.apiVersion) << "." + << VK_VERSION_MINOR(deviceProperties.apiVersion) << "." + << VK_VERSION_PATCH(deviceProperties.apiVersion) << std::endl; + } void checkFeatureSupport() { diff --git a/attachments/34_android.cpp b/attachments/34_android.cpp index c91ffde0..54284564 100644 --- a/attachments/34_android.cpp +++ b/attachments/34_android.cpp @@ -386,7 +386,7 @@ class HelloTriangleApplication }; // Required device extensions - const std::vector deviceExtensions = { + const std::vector requiredDeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME}; // Initialize Vulkan @@ -482,45 +482,44 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - // Pick physical device - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(deviceExtensions, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { - return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; - }); - }); - - return supportsGraphics && supportsAllRequiredExtensions; - }); - - if (devIter != devices.end()) - { - physicalDevice = *devIter; - - // Print device information - vk::PhysicalDeviceProperties deviceProperties = physicalDevice.getProperties(); - LOGI("Selected GPU: %s", deviceProperties.deviceName.data()); - } - else - { - throw std::runtime_error("Failed to find a suitable GPU"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtensions, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + + // Print device information + vk::PhysicalDeviceProperties deviceProperties = physicalDevice.getProperties(); + LOGI("Selected GPU: %s", deviceProperties.deviceName.data()); + } // Check feature support void checkFeatureSupport() @@ -609,8 +608,8 @@ class HelloTriangleApplication .pNext = &features2, .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo, - .enabledExtensionCount = static_cast(deviceExtensions.size()), - .ppEnabledExtensionNames = deviceExtensions.data()}; + .enabledExtensionCount = static_cast(requiredDeviceExtensions.size()), + .ppEnabledExtensionNames = requiredDeviceExtensions.data()}; // Create the device with the vk::DeviceCreateInfo device = vk::raii::Device(physicalDevice, vkDeviceCreateInfo); @@ -625,8 +624,8 @@ class HelloTriangleApplication vk::DeviceCreateInfo createInfo{ .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo, - .enabledExtensionCount = static_cast(deviceExtensions.size()), - .ppEnabledExtensionNames = deviceExtensions.data(), + .enabledExtensionCount = static_cast(requiredDeviceExtensions.size()), + .ppEnabledExtensionNames = requiredDeviceExtensions.data(), .pEnabledFeatures = &deviceFeatures}; device = vk::raii::Device(physicalDevice, createInfo); diff --git a/attachments/35_gltf_ktx.cpp b/attachments/35_gltf_ktx.cpp index 74330691..e77d89bb 100644 --- a/attachments/35_gltf_ktx.cpp +++ b/attachments/35_gltf_ktx.cpp @@ -471,98 +471,91 @@ class VulkanApplication #endif } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { - return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; - }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - - if (devIter != devices.end()) - { - physicalDevice = *devIter; - - // Check for Vulkan profile support - VpProfileProperties profileProperties; + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + + // Check for Vulkan profile support + VpProfileProperties profileProperties; #if PLATFORM_ANDROID - strcpy(profileProperties.name, VP_KHR_ROADMAP_2022_NAME); + strcpy( profileProperties.name, VP_KHR_ROADMAP_2022_NAME ); #else - strcpy(profileProperties.profileName, VP_KHR_ROADMAP_2022_NAME); + strcpy( profileProperties.profileName, VP_KHR_ROADMAP_2022_NAME ); #endif - profileProperties.specVersion = VP_KHR_ROADMAP_2022_SPEC_VERSION; + profileProperties.specVersion = VP_KHR_ROADMAP_2022_SPEC_VERSION; - VkBool32 supported = VK_FALSE; - bool result = false; + VkBool32 supported = VK_FALSE; + bool result = false; #if PLATFORM_ANDROID - // Create a vp::ProfileDesc from our VpProfileProperties - vp::ProfileDesc profileDesc = { - profileProperties.name, - profileProperties.specVersion}; - - // Use vp::GetProfileSupport for Android - result = vp::GetProfileSupport( - *physicalDevice, // Pass the physical device directly - &profileDesc, // Pass the profile description - &supported // Output parameter for support status - ); + // Create a vp::ProfileDesc from our VpProfileProperties + vp::ProfileDesc profileDesc = { profileProperties.name, profileProperties.specVersion }; + + // Use vp::GetProfileSupport for Android + result = vp::GetProfileSupport( *physicalDevice, // Pass the physical device directly + &profileDesc, // Pass the profile description + &supported // Output parameter for support status + ); #else - // Use vpGetPhysicalDeviceProfileSupport for Desktop - VkResult vk_result = vpGetPhysicalDeviceProfileSupport( - *instance, - *physicalDevice, - &profileProperties, - &supported); - result = vk_result == static_cast(vk::Result::eSuccess); + // Use vpGetPhysicalDeviceProfileSupport for Desktop + VkResult vk_result = vpGetPhysicalDeviceProfileSupport( *instance, *physicalDevice, &profileProperties, &supported ); + result = vk_result == static_cast( vk::Result::eSuccess ); #endif - const char *name = nullptr; + const char * name = nullptr; #ifdef PLATFORM_ANDROID - name = profileProperties.name; + name = profileProperties.name; #else - name = profileProperties.profileName; + name = profileProperties.profileName; #endif - if (result && supported == VK_TRUE) - { - appInfo.profileSupported = true; - appInfo.profile = profileProperties; - LOGI("Device supports Vulkan profile: %s", name); - } - else - { - LOGI("Device does not support Vulkan profile: %s", name); - } - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + if ( result && supported == VK_TRUE ) + { + appInfo.profileSupported = true; + appInfo.profile = profileProperties; + LOGI( "Device supports Vulkan profile: %s", name ); + } + else + { + LOGI( "Device does not support Vulkan profile: %s", name ); + } + } void createLogicalDevice() { diff --git a/attachments/36_multiple_objects.cpp b/attachments/36_multiple_objects.cpp index b43d0084..53a9a934 100644 --- a/attachments/36_multiple_objects.cpp +++ b/attachments/36_multiple_objects.cpp @@ -544,98 +544,91 @@ class VulkanApplication #endif } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { - return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; - }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - - if (devIter != devices.end()) - { - physicalDevice = *devIter; - - // Check for Vulkan profile support - VpProfileProperties profileProperties; + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + + // Check for Vulkan profile support + VpProfileProperties profileProperties; #if PLATFORM_ANDROID - strcpy(profileProperties.name, VP_KHR_ROADMAP_2022_NAME); + strcpy( profileProperties.name, VP_KHR_ROADMAP_2022_NAME ); #else - strcpy(profileProperties.profileName, VP_KHR_ROADMAP_2022_NAME); + strcpy( profileProperties.profileName, VP_KHR_ROADMAP_2022_NAME ); #endif - profileProperties.specVersion = VP_KHR_ROADMAP_2022_SPEC_VERSION; + profileProperties.specVersion = VP_KHR_ROADMAP_2022_SPEC_VERSION; - VkBool32 supported = VK_FALSE; - bool result = false; + VkBool32 supported = VK_FALSE; + bool result = false; #if PLATFORM_ANDROID - // Create a vp::ProfileDesc from our VpProfileProperties - vp::ProfileDesc profileDesc = { - profileProperties.name, - profileProperties.specVersion}; - - // Use vp::GetProfileSupport for Android - result = vp::GetProfileSupport( - *physicalDevice, // Pass the physical device directly - &profileDesc, // Pass the profile description - &supported // Output parameter for support status - ); + // Create a vp::ProfileDesc from our VpProfileProperties + vp::ProfileDesc profileDesc = { profileProperties.name, profileProperties.specVersion }; + + // Use vp::GetProfileSupport for Android + result = vp::GetProfileSupport( *physicalDevice, // Pass the physical device directly + &profileDesc, // Pass the profile description + &supported // Output parameter for support status + ); #else - // Use vpGetPhysicalDeviceProfileSupport for Desktop - VkResult vk_result = vpGetPhysicalDeviceProfileSupport( - *instance, - *physicalDevice, - &profileProperties, - &supported); - result = vk_result == static_cast(vk::Result::eSuccess); + // Use vpGetPhysicalDeviceProfileSupport for Desktop + VkResult vk_result = vpGetPhysicalDeviceProfileSupport( *instance, *physicalDevice, &profileProperties, &supported ); + result = vk_result == static_cast( vk::Result::eSuccess ); #endif - const char *name = nullptr; + const char * name = nullptr; #ifdef PLATFORM_ANDROID - name = profileProperties.name; + name = profileProperties.name; #else - name = profileProperties.profileName; + name = profileProperties.profileName; #endif - if (result && supported == VK_TRUE) - { - appInfo.profileSupported = true; - appInfo.profile = profileProperties; - LOGI("Device supports Vulkan profile: %s", name); - } - else - { - LOGI("Device does not support Vulkan profile: %s", name); - } - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + if ( result && supported == VK_TRUE ) + { + appInfo.profileSupported = true; + appInfo.profile = profileProperties; + LOGI( "Device supports Vulkan profile: %s", name ); + } + else + { + LOGI( "Device does not support Vulkan profile: %s", name ); + } + } void createLogicalDevice() { diff --git a/attachments/37_multithreading.cpp b/attachments/37_multithreading.cpp index 4a04029e..35dbc073 100644 --- a/attachments/37_multithreading.cpp +++ b/attachments/37_multithreading.cpp @@ -586,41 +586,47 @@ class MultithreadedApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().dynamicRendering && - features.template get().extendedDynamicState; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/attachments/38_ray_tracing.cpp b/attachments/38_ray_tracing.cpp index 873b5f10..5ef2fb05 100644 --- a/attachments/38_ray_tracing.cpp +++ b/attachments/38_ray_tracing.cpp @@ -396,58 +396,59 @@ class VulkanRaytracingApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - void pickPhysicalDevice() - { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if( - devices, - [&](auto const &device) { - // Check if the device supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - - // Check if any of the queue families support graphics operations - auto queueFamilies = device.getQueueFamilyProperties(); - bool supportsGraphics = - std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); - - // Check if all required device extensions are available - auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); - bool supportsAllRequiredExtensions = - std::ranges::all_of(requiredDeviceExtension, - [&availableDeviceExtensions](auto const &requiredDeviceExtension) { - return std::ranges::any_of(availableDeviceExtensions, - [requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; }); - }); - - auto features = device.template getFeatures2(); - bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && - features.template get().dynamicRendering && - features.template get().extendedDynamicState && - features.template get().descriptorBindingSampledImageUpdateAfterBind && - features.template get().descriptorBindingPartiallyBound && - features.template get().descriptorBindingVariableDescriptorCount && - features.template get().runtimeDescriptorArray && - features.template get().shaderSampledImageArrayNonUniformIndexing && - features.template get().bufferDeviceAddress && - features.template get().accelerationStructure && - features.template get().rayQuery; - - return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; - }); - if (devIter != devices.end()) - { - physicalDevice = *devIter; - } - else - { - throw std::runtime_error("failed to find a suitable GPU!"); - } - } + bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) + { + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features + auto features = physicalDevice.template getFeatures2(); + bool supportsRequiredFeatures = features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().extendedDynamicState && + features.template get().descriptorBindingSampledImageUpdateAfterBind && + features.template get().descriptorBindingPartiallyBound && + features.template get().descriptorBindingVariableDescriptorCount && + features.template get().runtimeDescriptorArray && + features.template get().shaderSampledImageArrayNonUniformIndexing && + features.template get().bufferDeviceAddress && + features.template get().accelerationStructure && + features.template get().rayQuery; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + void pickPhysicalDevice() + { + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; + } void createLogicalDevice() { diff --git a/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc b/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc index d44738e4..ccd9ce27 100644 --- a/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc +++ b/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc @@ -4,7 +4,7 @@ == Selecting a physical device -After initializing the Vulkan library through a VkInstance we need to look for +After initializing the Vulkan library through a vk::raii::Instance we need to look for and select a graphics card in the system that supports the features we need. In fact, we can select any number of graphics cards and use them simultaneously, but in this tutorial we'll stick to the first graphics card that suits our needs. @@ -14,19 +14,20 @@ We'll add a function `pickPhysicalDevice` and add a call to it in the [,c++] ---- -void initVulkan() { +void initVulkan() +{ createInstance(); setupDebugMessenger(); pickPhysicalDevice(); } -void pickPhysicalDevice() { - +void pickPhysicalDevice() +{ } ---- The graphics card that we'll end up selecting will be stored in a -VkPhysicalDevice handle added as a new class member. +vk::raii::PhysicalDevice added as a new class member. [,c++] ---- @@ -38,7 +39,7 @@ querying just the number. [,c++] ---- -auto devices = instance.enumeratePhysicalDevices() +auto physicalDevices = instance.enumeratePhysicalDevices() ---- If there are no devices with Vulkan support, then there is no point going @@ -46,7 +47,8 @@ further. [,c++] ---- -if (devices.empty()) { +if (physicalDevices.empty()) +{ throw std::runtime_error("failed to find GPUs with Vulkan support!"); } ---- @@ -58,8 +60,8 @@ add to that function. [,c++] ---- -for (const auto& device : devices) { - physicalDevice = device; +for (physicalDevice : physicalDevices) +{ break; } ---- @@ -68,20 +70,20 @@ for (const auto& device : devices) { To evaluate the suitability of a device, we can start by querying for some details. Basic device properties like the name, type and supported Vulkan -version can be queried using vkGetPhysicalDeviceProperties. +version can be queried using vk::raii::PhysicalDevice::getProperties. [,c++] ---- -auto deviceProperties = device.getProperties(); +auto deviceProperties = physicalDevice.getProperties(); ---- The support for optional features like texture compression, 64-bit floats and multi viewport rendering (useful for VR) can be queried using -vkGetPhysicalDeviceFeatures: +vk::raii::PhysicalDevice::getFeatures: [,c++] ---- -auto deviceFeatures = device.getFeatures(); +auto deviceFeatures = physicalDevice.getFeatures(); ---- There are more details that can be queried from devices that we'll discuss later @@ -93,7 +95,8 @@ function would look like this: [,c++] ---- -bool isDeviceSuitable(vk::raii::PhysicalDevice physicalDevice) { +bool isDeviceSuitable(vk::raii::PhysicalDevice const & physicalDevice) +{ auto deviceProperties = physicalDevice.getProperties(); auto deviceFeatures = physicalDevice.getFeatures(); @@ -117,17 +120,21 @@ something like that as follows: ... -void pickPhysicalDevice() { - auto devices = vk::raii::PhysicalDevices( instance ); - if (devices.empty()) { +void pickPhysicalDevice() +{ + auto physicalDevices = vk::raii::PhysicalDevices( instance ); + if (physicalDevices.empty()) + { throw std::runtime_error( "failed to find GPUs with Vulkan support!" ); } + // Use an ordered map to automatically sort candidates by increasing score std::multimap candidates; - for (const auto& device : devices) { - auto deviceProperties = device.getProperties(); - auto deviceFeatures = device.getFeatures(); + for (const auto& pd : physicalDevices) + { + auto deviceProperties = pd.getProperties(); + auto deviceFeatures = pd.getFeatures(); uint32_t score = 0; // Discrete GPUs have a significant performance advantage @@ -139,16 +146,20 @@ void pickPhysicalDevice() { score += deviceProperties.limits.maxImageDimension2D; // Application can't function without geometry shaders - if (!deviceFeatures.geometryShader) { + if (!deviceFeatures.geometryShader) + { continue; } - candidates.insert(std::make_pair(score, device)); + candidates.insert(std::make_pair(score, pd)); } // Check if the best candidate is suitable at all - if (candidates.rbegin()->first > 0) { + if (!candidates.empty() && candidates.rbegin()->first > 0) + { physicalDevice = candidates.rbegin()->second; - } else { + } + else + { throw std::runtime_error("failed to find a suitable GPU!"); } } @@ -158,53 +169,28 @@ You don't need to implement all that for this tutorial, but it's to give you an idea of how you could design your device selection process. Of course, you can also display the names of the choices and allow the user to select. -Because we're just starting out, Vulkan 1.3 support is the only thing we need, - and therefore we'll search for that and the extensions that we actually are - going to be demonstrating: +For this tutorial, we will use four criteria that must all be met by a physical device in order +to be selected: +- support of Vulkan 1.3, +- a queue family that supports graphics operations, +- support of all required extensions (here we only need vk::KHRSwapchainExtensionName), and +- support of all required features. + +=== API version check + +To check for Vulkan 1.3 support, you can check the apiVersion of the physical device properties: [,c++] ---- -std::vector deviceExtensions = { - vk::KHRSwapchainExtensionName}; - -void pickPhysicalDevice() { - std::vector devices = instance.enumeratePhysicalDevices(); - const auto devIter = std::ranges::find_if(devices, - [&](auto const & device) { - auto queueFamilies = device.getQueueFamilyProperties(); - bool isSuitable = device.getProperties().apiVersion >= VK_API_VERSION_1_3; - const auto qfpIter = std::ranges::find_if(queueFamilies, - []( vk::QueueFamilyProperties const & qfp ) - { - return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast(0); - } ); - isSuitable = isSuitable && ( qfpIter != queueFamilies.end() ); - auto extensions = device.enumerateDeviceExtensionProperties( ); - bool found = true; - for (auto const & extension : deviceExtensions) { - auto extensionIter = std::ranges::find_if(extensions, [extension](auto const & ext) {return strcmp(ext.extensionName, extension) == 0;}); - found = found && extensionIter != extensions.end(); - } - isSuitable = isSuitable && found; - if (isSuitable) { - physicalDevice = device; - } - return isSuitable; - }); - if (devIter == devices.end()) { - throw std::runtime_error("failed to find a suitable GPU!"); - } -} +bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; ---- -In the next section, we'll discuss the first real required feature to check for. - -== Queue families +=== Queue family check It has been briefly touched upon before that almost every operation in Vulkan, anything from drawing to uploading textures, requires commands to be submitted to a queue. There are different types of queues that originate from different -*queue families,* and each family of queues allows only a subset of commands. For +*queue families*, and each family of queues allows only a subset of commands. For example, there could be a queue family that only allows processing of compute commands or one that only allows memory transfer related commands. @@ -215,17 +201,90 @@ could look like this: [,c++] ---- -uint32_t findQueueFamilies(vk::raii::PhysicalDevice physicalDevice) { - // find the index of the first queue family that supports graphics - std::vector queueFamilyProperties = physicalDevice.getQueueFamilyProperties(); +auto queueFamilies = physicalDevice.getQueueFamilyProperties(); +bool supportsGraphics = + std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); +---- + +=== Required extension check - // get the first index into queueFamilyProperties which supports graphics - auto graphicsQueueFamilyProperty = - std::find_if( queueFamilyProperties.begin(), - queueFamilyProperties.end(), - []( vk::QueueFamilyProperties const & qfp ) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; } ); +Currently, we only need one extension: vk::KHRSwapchainExtensionName. But regardless of +how many extensions we need, we must verify that each required device extension +is actually supported by the physical device: +[,c++] +---- +std::vector requiredDeviceExtension = {vk::KHRSwapchainExtensionName}; + +auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); +bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); +---- + +=== Required feature check + +Finally, we need to check that all optionally supported required features are actually supported: + +[,c++] +---- +auto features = physicalDevice.template getFeatures2(); +bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; +---- + +== The complete function + +When we put all these pieces together, we get this function for selecting a physical device: + +[,c++] +---- +std::vector requiredDeviceExtension = {vk::KHRSwapchainExtensionName}; + +bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) +{ + // Check if the physicalDevice supports the Vulkan 1.3 API version + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + + // Check if any of the queue families support graphics operations + auto queueFamilies = physicalDevice.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } ); + + // Check if all required physicalDevice extensions are available + auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = + std::ranges::all_of( requiredDeviceExtension, + [&availableDeviceExtensions]( auto const & requiredDeviceExtension ) + { + return std::ranges::any_of( availableDeviceExtensions, + [requiredDeviceExtension]( auto const & availableDeviceExtension ) + { return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } ); + } ); + + // Check if the physicalDevice supports the required features (dynamic rendering and extended dynamic state) + auto features = + physicalDevice + .template getFeatures2(); + bool supportsRequiredFeatures = features.template get().dynamicRendering && + features.template get().extendedDynamicState; + + // Return true if the physicalDevice meets all the criteria + return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; +} - return static_cast( std::distance( queueFamilyProperties.begin(), graphicsQueueFamilyProperty ) ); +void pickPhysicalDevice() +{ + std::vector physicalDevices = instance.enumeratePhysicalDevices(); + auto const devIter = std::ranges::find_if( physicalDevices, [&]( auto const & physicalDevice ) { return isDeviceSuitable( physicalDevice ); } ); + if ( devIter == physicalDevices.end() ) + { + throw std::runtime_error( "failed to find a suitable GPU!" ); + } + physicalDevice = *devIter; } ---- From 41e3dea02cd737176ea631b7d7c33690e3edea52 Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Thu, 19 Feb 2026 14:29:02 +0100 Subject: [PATCH 2/2] change from VK_API_VERSION_1_3 to vk::ApiVersion13 --- attachments/03_physical_device_selection.cpp | 2 +- .../00_Setup/03_Physical_devices_and_queue_families.adoc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/attachments/03_physical_device_selection.cpp b/attachments/03_physical_device_selection.cpp index 67366b76..6c407cec 100644 --- a/attachments/03_physical_device_selection.cpp +++ b/attachments/03_physical_device_selection.cpp @@ -152,7 +152,7 @@ class HelloTriangleApplication bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) { // Check if the physicalDevice supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= vk::ApiVersion13; // Check if any of the queue families support graphics operations auto queueFamilies = physicalDevice.getQueueFamilyProperties(); diff --git a/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc b/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc index ccd9ce27..cdf164c7 100644 --- a/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc +++ b/en/03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc @@ -182,7 +182,7 @@ To check for Vulkan 1.3 support, you can check the apiVersion of the physical de [,c++] ---- -bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; +bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= vk::ApiVersion13; ---- === Queue family check @@ -248,7 +248,7 @@ std::vector requiredDeviceExtension = {vk::KHRSwapchainExtensionNam bool isDeviceSuitable( vk::raii::PhysicalDevice const & physicalDevice ) { // Check if the physicalDevice supports the Vulkan 1.3 API version - bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= VK_API_VERSION_1_3; + bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= vk::ApiVersion13; // Check if any of the queue families support graphics operations auto queueFamilies = physicalDevice.getQueueFamilyProperties();