From 275f4e7c627f0f14c7afe426a9ccec955423e00c Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Wed, 25 Feb 2026 14:11:27 +0100 Subject: [PATCH] Align docu in 01_Swap_chain.adoc and the sources in 06_swap_chain_creation.cpp --- attachments/03_physical_device_selection.cpp | 80 +++-- attachments/04_logical_device.cpp | 80 +++-- attachments/05_window_surface.cpp | 80 +++-- attachments/06_swap_chain_creation.cpp | 103 +++---- attachments/07_image_views.cpp | 105 +++---- attachments/08_graphics_pipeline.cpp | 105 +++---- attachments/09_shader_modules.cpp | 107 +++---- attachments/10_fixed_functions.cpp | 109 +++---- attachments/12_graphics_pipeline_complete.cpp | 109 +++---- attachments/14_command_buffers.cpp | 27 +- attachments/15_hello_triangle.cpp | 109 +++---- attachments/16_frames_in_flight.cpp | 111 +++---- attachments/17_swap_chain_recreation.cpp | 123 ++++---- attachments/19_vertex_buffer.cpp | 109 +++---- attachments/20_staging_buffer.cpp | 109 +++---- attachments/21_index_buffer.cpp | 109 +++---- attachments/22_descriptor_layout.cpp | 109 +++---- attachments/23_descriptor_sets.cpp | 107 +++---- attachments/24_texture_image.cpp | 109 +++---- attachments/25_sampler.cpp | 109 +++---- attachments/26_texture_mapping.cpp | 109 +++---- attachments/27_depth_buffering.cpp | 109 +++---- attachments/28_model_loading.cpp | 113 ++++---- attachments/29_mipmapping.cpp | 113 ++++---- attachments/30_multisampling.cpp | 113 ++++---- attachments/31_compute_shader.cpp | 113 ++++---- attachments/32_ecosystem_utilities.cpp | 99 ++++--- attachments/33_vulkan_profiles.cpp | 109 +++---- attachments/34_android.cpp | 99 ++++--- attachments/35_gltf_ktx.cpp | 173 +++++------ attachments/36_multiple_objects.cpp | 173 +++++------ attachments/37_multithreading.cpp | 109 +++---- attachments/38_ray_tracing.cpp | 172 ++++++----- .../01_Presentation/01_Swap_chain.adoc | 274 +++++++++--------- 34 files changed, 2024 insertions(+), 1863 deletions(-) diff --git a/attachments/03_physical_device_selection.cpp b/attachments/03_physical_device_selection.cpp index 6c407cec..5838f87a 100644 --- a/attachments/03_physical_device_selection.cpp +++ b/attachments/03_physical_device_selection.cpp @@ -149,47 +149,45 @@ class HelloTriangleApplication debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT); } - 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::ApiVersion13; - - // 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; - } + 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::ApiVersion13; + + // 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 1e649537..1bb10257 100644 --- a/attachments/04_logical_device.cpp +++ b/attachments/04_logical_device.cpp @@ -154,47 +154,45 @@ class HelloTriangleApplication debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT); } - 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; - } + 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 b237c77b..1de42860 100644 --- a/attachments/05_window_surface.cpp +++ b/attachments/05_window_surface.cpp @@ -162,47 +162,45 @@ 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().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; - } + 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 65d38d55..d81c8cf2 100644 --- a/attachments/06_swap_chain_creation.cpp +++ b/attachments/06_swap_chain_creation.cpp @@ -170,47 +170,45 @@ 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().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; - } + 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() { @@ -255,11 +253,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -268,7 +273,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -294,7 +299,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -303,9 +308,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/07_image_views.cpp b/attachments/07_image_views.cpp index 3b67a99d..69cf473e 100644 --- a/attachments/07_image_views.cpp +++ b/attachments/07_image_views.cpp @@ -171,47 +171,45 @@ 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().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; - } + 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() { @@ -256,11 +254,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -269,7 +274,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -281,7 +286,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -307,7 +312,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -316,9 +321,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/08_graphics_pipeline.cpp b/attachments/08_graphics_pipeline.cpp index b35c5d7b..e082063a 100644 --- a/attachments/08_graphics_pipeline.cpp +++ b/attachments/08_graphics_pipeline.cpp @@ -172,47 +172,45 @@ 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().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; - } + 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() { @@ -257,11 +255,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -270,7 +275,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -282,7 +287,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -312,7 +317,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -321,9 +326,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/09_shader_modules.cpp b/attachments/09_shader_modules.cpp index d61d14b3..ef417f30 100644 --- a/attachments/09_shader_modules.cpp +++ b/attachments/09_shader_modules.cpp @@ -173,49 +173,47 @@ 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 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; - } + 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() { @@ -265,11 +263,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -278,7 +283,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -333,7 +338,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -342,9 +347,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/10_fixed_functions.cpp b/attachments/10_fixed_functions.cpp index 8d1b1417..27d545fa 100644 --- a/attachments/10_fixed_functions.cpp +++ b/attachments/10_fixed_functions.cpp @@ -175,49 +175,47 @@ 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 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; - } + 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() { @@ -267,11 +265,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -280,7 +285,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -292,7 +297,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -357,7 +362,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -366,9 +371,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/12_graphics_pipeline_complete.cpp b/attachments/12_graphics_pipeline_complete.cpp index a3c1056a..88641c94 100644 --- a/attachments/12_graphics_pipeline_complete.cpp +++ b/attachments/12_graphics_pipeline_complete.cpp @@ -176,49 +176,47 @@ 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 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; - } + 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() { @@ -268,11 +266,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -281,7 +286,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -293,7 +298,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -374,7 +379,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -383,9 +388,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/14_command_buffers.cpp b/attachments/14_command_buffers.cpp index 7a90e90a..18c6bd11 100644 --- a/attachments/14_command_buffers.cpp +++ b/attachments/14_command_buffers.cpp @@ -181,7 +181,7 @@ class HelloTriangleApplication surface = vk::raii::SurfaceKHR(instance, _surface); } - bool isDeviceSuitable(vk::raii::PhysicalDevice const &physicalDevice) + 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; @@ -270,11 +270,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -283,7 +290,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -295,7 +302,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -389,7 +396,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -398,9 +405,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/15_hello_triangle.cpp b/attachments/15_hello_triangle.cpp index 59b5f7a8..acf8c45a 100644 --- a/attachments/15_hello_triangle.cpp +++ b/attachments/15_hello_triangle.cpp @@ -189,50 +189,48 @@ 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().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; - } + 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() { @@ -281,11 +279,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -294,7 +299,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -516,7 +521,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -525,9 +530,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/16_frames_in_flight.cpp b/attachments/16_frames_in_flight.cpp index 08805d38..c7408f21 100644 --- a/attachments/16_frames_in_flight.cpp +++ b/attachments/16_frames_in_flight.cpp @@ -192,50 +192,48 @@ 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().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; - } + 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() { @@ -284,11 +282,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -297,7 +302,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -309,7 +314,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -541,7 +546,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -550,9 +555,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/17_swap_chain_recreation.cpp b/attachments/17_swap_chain_recreation.cpp index 9f53abf7..23af6bef 100644 --- a/attachments/17_swap_chain_recreation.cpp +++ b/attachments/17_swap_chain_recreation.cpp @@ -67,7 +67,7 @@ class HelloTriangleApplication std::vector presentCompleteSemaphores; std::vector renderFinishedSemaphores; std::vector inFlightFences; - uint32_t frameIndex = 0; + uint32_t frameIndex = 0; bool framebufferResized = false; @@ -225,50 +225,48 @@ 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().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; - } + 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() { @@ -317,11 +315,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -330,7 +335,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -342,7 +347,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -547,10 +552,10 @@ class HelloTriangleApplication queue.submit(submitInfo, *inFlightFences[frameIndex]); const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1, - .pWaitSemaphores = &*renderFinishedSemaphores[imageIndex], - .swapchainCount = 1, - .pSwapchains = &*swapChain, - .pImageIndices = &imageIndex}; + .pWaitSemaphores = &*renderFinishedSemaphores[imageIndex], + .swapchainCount = 1, + .pSwapchains = &*swapChain, + .pImageIndices = &imageIndex}; result = queue.presentKHR(presentInfoKHR); // Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result // here and does not need to be caught by an exception. @@ -564,7 +569,7 @@ class HelloTriangleApplication // There are no other success codes than eSuccess; on any error code, presentKHR already threw an exception. assert(result == vk::Result::eSuccess); } - frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT; + frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT; } [[nodiscard]] vk::raii::ShaderModule createShaderModule(const std::vector &code) const @@ -594,7 +599,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -603,9 +608,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/19_vertex_buffer.cpp b/attachments/19_vertex_buffer.cpp index ac17551b..ec98287b 100644 --- a/attachments/19_vertex_buffer.cpp +++ b/attachments/19_vertex_buffer.cpp @@ -254,49 +254,47 @@ 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 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; - } + 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() { @@ -341,11 +339,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -354,7 +359,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -366,7 +371,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -652,7 +657,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -661,9 +666,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/20_staging_buffer.cpp b/attachments/20_staging_buffer.cpp index 982e1fc2..d03ba4cc 100644 --- a/attachments/20_staging_buffer.cpp +++ b/attachments/20_staging_buffer.cpp @@ -254,49 +254,47 @@ 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 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; - } + 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() { @@ -341,11 +339,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -354,7 +359,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -366,7 +371,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -672,7 +677,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -681,9 +686,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/21_index_buffer.cpp b/attachments/21_index_buffer.cpp index a1ce7bef..583b238c 100644 --- a/attachments/21_index_buffer.cpp +++ b/attachments/21_index_buffer.cpp @@ -261,49 +261,47 @@ 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 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; - } + 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() { @@ -348,11 +346,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -361,7 +366,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -373,7 +378,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -698,7 +703,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -707,9 +712,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/22_descriptor_layout.cpp b/attachments/22_descriptor_layout.cpp index 9f3e0a9c..ad723eae 100644 --- a/attachments/22_descriptor_layout.cpp +++ b/attachments/22_descriptor_layout.cpp @@ -279,49 +279,47 @@ 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 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; - } + 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() { @@ -366,11 +364,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -379,7 +384,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -391,7 +396,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -758,7 +763,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -767,9 +772,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/23_descriptor_sets.cpp b/attachments/23_descriptor_sets.cpp index 653cd454..4ea08223 100644 --- a/attachments/23_descriptor_sets.cpp +++ b/attachments/23_descriptor_sets.cpp @@ -284,49 +284,47 @@ 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 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; - } + 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() { @@ -371,11 +369,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -384,7 +389,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -396,7 +401,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -786,7 +791,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -797,7 +802,7 @@ class HelloTriangleApplication vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/24_texture_image.cpp b/attachments/24_texture_image.cpp index 55687d2f..6c3aa203 100644 --- a/attachments/24_texture_image.cpp +++ b/attachments/24_texture_image.cpp @@ -291,49 +291,47 @@ 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 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; - } + 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() { @@ -378,11 +376,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -391,7 +396,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -403,7 +408,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -895,7 +900,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -904,9 +909,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/25_sampler.cpp b/attachments/25_sampler.cpp index 44e7a1a4..b4771377 100644 --- a/attachments/25_sampler.cpp +++ b/attachments/25_sampler.cpp @@ -295,49 +295,47 @@ 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().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; - } + 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() { @@ -381,11 +379,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -394,7 +399,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -406,7 +411,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -931,7 +936,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -940,9 +945,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/26_texture_mapping.cpp b/attachments/26_texture_mapping.cpp index 2d6fb045..9ee78936 100644 --- a/attachments/26_texture_mapping.cpp +++ b/attachments/26_texture_mapping.cpp @@ -297,49 +297,47 @@ 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().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; - } + 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() { @@ -383,11 +381,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -396,7 +401,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -408,7 +413,7 @@ class HelloTriangleApplication assert(swapChainImageViews.empty()); vk::ImageViewCreateInfo imageViewCreateInfo{.viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -996,7 +1001,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1005,9 +1010,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/27_depth_buffering.cpp b/attachments/27_depth_buffering.cpp index 2a1c7aae..b6c3fcd4 100644 --- a/attachments/27_depth_buffering.cpp +++ b/attachments/27_depth_buffering.cpp @@ -312,49 +312,47 @@ 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().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; - } + 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() { @@ -398,11 +396,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -411,7 +416,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -426,7 +431,7 @@ class HelloTriangleApplication .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -1099,7 +1104,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1108,9 +1113,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/28_model_loading.cpp b/attachments/28_model_loading.cpp index 9e1543f3..669b4054 100644 --- a/attachments/28_model_loading.cpp +++ b/attachments/28_model_loading.cpp @@ -319,49 +319,47 @@ 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().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; - } + 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() { @@ -405,11 +403,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -418,7 +423,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -433,7 +438,7 @@ class HelloTriangleApplication .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -489,8 +494,8 @@ class HelloTriangleApplication .depthBoundsTestEnable = vk::False, .stencilTestEnable = vk::False}; vk::PipelineColorBlendAttachmentState colorBlendAttachment{ - .blendEnable = vk::False, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; + .blendEnable = vk::False, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo colorBlending{ .logicOpEnable = vk::False, .logicOp = vk::LogicOp::eCopy, @@ -1153,7 +1158,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1162,9 +1167,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/29_mipmapping.cpp b/attachments/29_mipmapping.cpp index 5618bceb..ccd168d3 100644 --- a/attachments/29_mipmapping.cpp +++ b/attachments/29_mipmapping.cpp @@ -319,49 +319,47 @@ 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().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; - } + 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() { @@ -405,11 +403,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -418,7 +423,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -433,7 +438,7 @@ class HelloTriangleApplication .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -489,8 +494,8 @@ class HelloTriangleApplication .depthBoundsTestEnable = vk::False, .stencilTestEnable = vk::False}; vk::PipelineColorBlendAttachmentState colorBlendAttachment{ - .blendEnable = vk::False, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; + .blendEnable = vk::False, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo colorBlending{ .logicOpEnable = vk::False, .logicOp = vk::LogicOp::eCopy, @@ -1223,7 +1228,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1232,9 +1237,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) const + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/30_multisampling.cpp b/attachments/30_multisampling.cpp index 8b5812ad..42fd9a7d 100644 --- a/attachments/30_multisampling.cpp +++ b/attachments/30_multisampling.cpp @@ -328,49 +328,47 @@ 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().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; - } + 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() { @@ -414,11 +412,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -427,7 +432,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -442,7 +447,7 @@ class HelloTriangleApplication .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -498,8 +503,8 @@ class HelloTriangleApplication .depthBoundsTestEnable = vk::False, .stencilTestEnable = vk::False}; vk::PipelineColorBlendAttachmentState colorBlendAttachment{ - .blendEnable = vk::False, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; + .blendEnable = vk::False, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo colorBlending{ .logicOpEnable = vk::False, .logicOp = vk::LogicOp::eCopy, @@ -1286,7 +1291,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1295,9 +1300,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) const + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/31_compute_shader.cpp b/attachments/31_compute_shader.cpp index f6513842..b6266f77 100644 --- a/attachments/31_compute_shader.cpp +++ b/attachments/31_compute_shader.cpp @@ -293,52 +293,50 @@ class ComputeShaderApplication 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().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() + 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(); @@ -386,11 +384,18 @@ void createLogicalDevice() void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -399,7 +404,7 @@ void createLogicalDevice() .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -939,7 +944,7 @@ void createLogicalDevice() return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -948,9 +953,9 @@ void createLogicalDevice() vk::PresentModeKHR::eFifo; } - [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) const + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/32_ecosystem_utilities.cpp b/attachments/32_ecosystem_utilities.cpp index 8538f50a..89085f14 100644 --- a/attachments/32_ecosystem_utilities.cpp +++ b/attachments/32_ecosystem_utilities.cpp @@ -348,41 +348,39 @@ 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; } ); - } ); - - // 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(); - } + 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() { @@ -543,11 +541,18 @@ class HelloTriangleApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -556,7 +561,7 @@ class HelloTriangleApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -571,7 +576,7 @@ class HelloTriangleApplication .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -744,8 +749,8 @@ class HelloTriangleApplication .depthBoundsTestEnable = vk::False, .stencilTestEnable = vk::False}; vk::PipelineColorBlendAttachmentState colorBlendAttachment{ - .blendEnable = vk::False, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; + .blendEnable = vk::False, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo colorBlending{ .logicOpEnable = vk::False, .logicOp = vk::LogicOp::eCopy, @@ -755,7 +760,7 @@ class HelloTriangleApplication vk::DynamicState::eViewport, vk::DynamicState::eScissor}; vk::PipelineDynamicStateCreateInfo dynamicState{.dynamicStateCount = static_cast(dynamicStates.size()), .pDynamicStates = dynamicStates.data()}; - vk::PipelineLayoutCreateInfo pipelineLayoutInfo{.setLayoutCount = 1, .pSetLayouts = &*descriptorSetLayout, .pushConstantRangeCount = 0}; + vk::PipelineLayoutCreateInfo pipelineLayoutInfo{.setLayoutCount = 1, .pSetLayouts = &*descriptorSetLayout, .pushConstantRangeCount = 0}; pipelineLayout = vk::raii::PipelineLayout(device, pipelineLayoutInfo); @@ -1714,7 +1719,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1723,9 +1728,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) const + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/33_vulkan_profiles.cpp b/attachments/33_vulkan_profiles.cpp index cd5340e0..4b1268e5 100644 --- a/attachments/33_vulkan_profiles.cpp +++ b/attachments/33_vulkan_profiles.cpp @@ -129,7 +129,7 @@ class HelloTriangleApplication std::vector renderFinishedSemaphores; std::vector inFlightFences; std::vector presentCompleteSemaphore; - uint32_t frameIndex = 0; + uint32_t frameIndex = 0; bool framebufferResized = false; vk::raii::Buffer vertexBuffer = nullptr; vk::raii::DeviceMemory vertexBufferMemory = nullptr; @@ -356,48 +356,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; } ); - } ); - - // 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; - } + 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() { @@ -505,20 +503,27 @@ class HelloTriangleApplication void createSwapChain() { - SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); - swapChainExtent = chooseSwapExtent(swapChainSupport.capabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(swapChainSupport.capabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, .imageArrayLayers = 1, .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, .imageSharingMode = vk::SharingMode::eExclusive, - .preTransform = swapChainSupport.capabilities.currentTransform, + .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(swapChainSupport.presentModes), + .presentMode = presentMode, .clipped = true}; swapChain = device.createSwapchainKHR(swapChainCreateInfo); @@ -1686,7 +1691,7 @@ class HelloTriangleApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1695,9 +1700,9 @@ class HelloTriangleApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/34_android.cpp b/attachments/34_android.cpp index 54284564..c32c6361 100644 --- a/attachments/34_android.cpp +++ b/attachments/34_android.cpp @@ -482,44 +482,42 @@ 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( 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()); - } + 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() @@ -637,20 +635,27 @@ class HelloTriangleApplication // Create swap chain void createSwapChain() { - SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); - swapChainExtent = chooseSwapExtent(swapChainSupport.capabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(swapChainSupport.capabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, .imageArrayLayers = 1, .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, .imageSharingMode = vk::SharingMode::eExclusive, - .preTransform = swapChainSupport.capabilities.currentTransform, + .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(swapChainSupport.presentModes), + .presentMode = presentMode, .clipped = true}; swapChain = device.createSwapchainKHR(swapChainCreateInfo); @@ -1470,7 +1475,7 @@ class HelloTriangleApplication } // Choose swap present mode - vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1480,9 +1485,9 @@ class HelloTriangleApplication } // Choose swap extent - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/35_gltf_ktx.cpp b/attachments/35_gltf_ktx.cpp index e77d89bb..107ef1b8 100644 --- a/attachments/35_gltf_ktx.cpp +++ b/attachments/35_gltf_ktx.cpp @@ -471,91 +471,89 @@ class VulkanApplication #endif } - 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; + 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 ); - } - } + 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() { @@ -604,11 +602,18 @@ class VulkanApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -617,7 +622,7 @@ class VulkanApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -632,7 +637,7 @@ class VulkanApplication .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -688,8 +693,8 @@ class VulkanApplication .depthBoundsTestEnable = vk::False, .stencilTestEnable = vk::False}; vk::PipelineColorBlendAttachmentState colorBlendAttachment{ - .blendEnable = vk::False, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; + .blendEnable = vk::False, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo colorBlending{ .logicOpEnable = vk::False, .logicOp = vk::LogicOp::eCopy, @@ -1474,7 +1479,7 @@ class VulkanApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1483,9 +1488,9 @@ class VulkanApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/36_multiple_objects.cpp b/attachments/36_multiple_objects.cpp index 53a9a934..7cd4b463 100644 --- a/attachments/36_multiple_objects.cpp +++ b/attachments/36_multiple_objects.cpp @@ -544,91 +544,89 @@ class VulkanApplication #endif } - 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; + 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 ); - } - } + 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() { @@ -677,11 +675,18 @@ class VulkanApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -690,7 +695,7 @@ class VulkanApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), + .presentMode = presentMode, .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); @@ -705,7 +710,7 @@ class VulkanApplication .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -761,8 +766,8 @@ class VulkanApplication .depthBoundsTestEnable = vk::False, .stencilTestEnable = vk::False}; vk::PipelineColorBlendAttachmentState colorBlendAttachment{ - .blendEnable = vk::False, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; + .blendEnable = vk::False, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo colorBlending{ .logicOpEnable = vk::False, .logicOp = vk::LogicOp::eCopy, @@ -1609,7 +1614,7 @@ class VulkanApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -1618,9 +1623,9 @@ class VulkanApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } diff --git a/attachments/37_multithreading.cpp b/attachments/37_multithreading.cpp index 35dbc073..dcb8edda 100644 --- a/attachments/37_multithreading.cpp +++ b/attachments/37_multithreading.cpp @@ -259,7 +259,7 @@ class MultithreadedApplication return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); return std::ranges::any_of(availablePresentModes, @@ -267,9 +267,10 @@ class MultithreadedApplication vk::PresentModeKHR::eMailbox : vk::PresentModeKHR::eFifo; } - [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) const + + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { - if (capabilities.currentExtent.width != 0xFFFFFFFF) + if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } @@ -586,47 +587,45 @@ class MultithreadedApplication 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().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; - } + 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() { @@ -677,11 +676,18 @@ class MultithreadedApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface)); + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, - .minImageCount = chooseSwapMinImageCount(surfaceCapabilities), + .minImageCount = minImageCount, .imageFormat = swapChainSurfaceFormat.format, .imageColorSpace = swapChainSurfaceFormat.colorSpace, .imageExtent = swapChainExtent, @@ -690,9 +696,8 @@ class MultithreadedApplication .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface)), - .clipped = true, - .oldSwapchain = *swapChain ? *swapChain : nullptr}; + .presentMode = presentMode, + .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -707,7 +712,7 @@ class MultithreadedApplication .format = swapChainSurfaceFormat.format, .components = {vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity}, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); diff --git a/attachments/38_ray_tracing.cpp b/attachments/38_ray_tracing.cpp index 5ef2fb05..97f2835b 100644 --- a/attachments/38_ray_tracing.cpp +++ b/attachments/38_ray_tracing.cpp @@ -139,7 +139,7 @@ class VulkanRaytracingApplication vk::raii::SwapchainKHR swapChain = nullptr; std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; + vk::SurfaceFormatKHR swapChainSurfaceFormat; vk::Extent2D swapChainExtent; std::vector swapChainImageViews; @@ -396,59 +396,57 @@ class VulkanRaytracingApplication 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().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; - } + 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() { @@ -525,13 +523,28 @@ class VulkanRaytracingApplication void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface); - swapChainImageFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(surface)); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - auto minImageCount = std::max(3u, surfaceCapabilities.minImageCount); - minImageCount = (surfaceCapabilities.maxImageCount > 0 && minImageCount > surfaceCapabilities.maxImageCount) ? surfaceCapabilities.maxImageCount : minImageCount; - vk::SwapchainCreateInfoKHR swapChainCreateInfo{ - .surface = surface, .minImageCount = minImageCount, .imageFormat = swapChainImageFormat, .imageColorSpace = vk::ColorSpaceKHR::eSrgbNonlinear, .imageExtent = swapChainExtent, .imageArrayLayers = 1, .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, .imageSharingMode = vk::SharingMode::eExclusive, .preTransform = surfaceCapabilities.currentTransform, .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR(surface)), .clipped = true}; + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); + + std::vector availablePresentModes = physicalDevice.getSurfacePresentModesKHR(*surface); + vk::PresentModeKHR presentMode = chooseSwapPresentMode(availablePresentModes); + + vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, + .minImageCount = minImageCount, + .imageFormat = swapChainSurfaceFormat.format, + .imageColorSpace = swapChainSurfaceFormat.colorSpace, + .imageExtent = swapChainExtent, + .imageArrayLayers = 1, + .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, + .imageSharingMode = vk::SharingMode::eExclusive, + .preTransform = surfaceCapabilities.currentTransform, + .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, + .presentMode = presentMode, + .clipped = true}; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -541,9 +554,9 @@ class VulkanRaytracingApplication { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}}; - for (auto& image : swapChainImages) + for (auto &image : swapChainImages) { imageViewCreateInfo.image = image; swapChainImageViews.emplace_back(device, imageViewCreateInfo); @@ -629,8 +642,8 @@ class VulkanRaytracingApplication .depthBoundsTestEnable = vk::False, .stencilTestEnable = vk::False}; vk::PipelineColorBlendAttachmentState colorBlendAttachment{ - .blendEnable = vk::False, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; + .blendEnable = vk::False, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; vk::PipelineColorBlendStateCreateInfo colorBlending{ .logicOpEnable = vk::False, .logicOp = vk::LogicOp::eCopy, @@ -672,7 +685,7 @@ class VulkanRaytracingApplication .pDynamicState = &dynamicState, .layout = *pipelineLayout, .renderPass = nullptr}, - {.colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat, .depthAttachmentFormat = depthFormat}}; + {.colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format, .depthAttachmentFormat = depthFormat}}; graphicsPipeline = vk::raii::Pipeline(device, nullptr, pipelineCreateInfoChain.get()); } @@ -1901,17 +1914,26 @@ class VulkanRaytracingApplication return shaderModule; } - static vk::Format chooseSwapSurfaceFormat(const std::vector &availableFormats) + static uint32_t chooseSwapMinImageCount(vk::SurfaceCapabilitiesKHR const &surfaceCapabilities) + { + auto minImageCount = std::max(3u, surfaceCapabilities.minImageCount); + if ((0 < surfaceCapabilities.maxImageCount) && (surfaceCapabilities.maxImageCount < minImageCount)) + { + minImageCount = surfaceCapabilities.maxImageCount; + } + return minImageCount; + } + + static vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector &availableFormats) { - const auto formatIt = std::ranges::find_if(availableFormats, - [](const auto &format) { - return format.format == vk::Format::eB8G8R8A8Srgb && - format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear; - }); - return formatIt != availableFormats.end() ? formatIt->format : availableFormats[0].format; + assert(!availableFormats.empty()); + const auto formatIt = std::ranges::find_if( + availableFormats, + [](const auto &format) { return format.format == vk::Format::eB8G8R8A8Srgb && format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear; }); + return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } - static vk::PresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes) + static vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) { return std::ranges::any_of(availablePresentModes, [](const vk::PresentModeKHR value) { return vk::PresentModeKHR::eMailbox == value; }) ? @@ -1919,7 +1941,7 @@ class VulkanRaytracingApplication vk::PresentModeKHR::eFifo; } - vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR &capabilities) + vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) { if (capabilities.currentExtent.width != std::numeric_limits::max()) { diff --git a/en/03_Drawing_a_triangle/01_Presentation/01_Swap_chain.adoc b/en/03_Drawing_a_triangle/01_Presentation/01_Swap_chain.adoc index 1956f867..5ffe0290 100644 --- a/en/03_Drawing_a_triangle/01_Presentation/01_Swap_chain.adoc +++ b/en/03_Drawing_a_triangle/01_Presentation/01_Swap_chain.adoc @@ -19,14 +19,14 @@ Not all graphics cards are capable of presenting images directly to a screen for various reasons, for example, because they are designed for servers and don't have any display outputs. Secondly, since image presentation is heavily tied into the window system and the surfaces associated with windows, it is not - part of the Vulkan core. You have to enable the `VK_KHR_swapchain` -device extension after querying for its support. +part of the Vulkan core. You have to enable the `VK_KHR_swapchain` device +extension after querying for its support. For that purpose we'll first extend the `createLogicalDevice` function to check if this extension is supported. We've previously seen how to list the -extensions that are supported by a `VkPhysicalDevice`, so doing that should +extensions that are supported by a `vk::raii::PhysicalDevice`, so doing that should be fairly straightforward. Note that the Vulkan header file provides a nice -macro `VK_KHR_SWAPCHAIN_EXTENSION_NAME` that is defined as +macro `vk::KHRSwapchainExtensionName` that is defined as `VK_KHR_swapchain`. The advantage of using this macro is that the compiler will catch misspellings. @@ -35,7 +35,7 @@ validation layers to enable. [,c++] ---- -std::vector deviceExtensions = { +std::vector requiredDeviceExtension = { vk::KHRSwapchainExtensionName}; ---- @@ -51,24 +51,29 @@ creation structure: [,c++] ---- -deviceCreateInfo.enabledExtensionCount = deviceExtensions.size(); -deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data(); +deviceCreateInfo.enabledExtensionCount = requiredDeviceExtension.size(); +deviceCreateInfo.ppEnabledExtensionNames = requiredDeviceExtension.data(); ---- Alternatively, we can do this at the construction and keep this very succinct: [,c++] ---- -std::vector deviceExtensions = { vk::KHRSwapchainExtensionName }; +std::vector requiredDeviceExtension = { vk::KHRSwapchainExtensionName }; + float queuePriority = 0.5f; -vk::DeviceQueueCreateInfo deviceQueueCreateInfo( {}, graphicsIndex, 1, &queuePriority ); -vk::DeviceCreateInfo deviceCreateInfo( {}, deviceQueueCreateInfo, {}, deviceExtensions ); +vk::DeviceQueueCreateInfo deviceQueueCreateInfo{.queueFamilyIndex = queueIndex, .queueCount = 1, .pQueuePriorities = &queuePriority}; +vk::DeviceCreateInfo deviceCreateInfo{.pNext = &featureChain.get(), + .queueCreateInfoCount = 1, + .pQueueCreateInfos = &deviceQueueCreateInfo, + .enabledExtensionCount = static_cast(requiredDeviceExtension.size()), + .ppEnabledExtensionNames = requiredDeviceExtension.data()}; ---- == Querying details of swap chain support Just checking if a swap chain is available is not enough because it may not - be compatible with our window surface. Creating a swap chain also +be compatible with our window surface. Creating a swap chain also involves a lot more settings than instance and device creation, so we need to query for some more details before we're able to proceed. @@ -85,17 +90,16 @@ next section. Let's start with the basic surface capabilities. These properties are straightforward to query and are returned into a single -`VkSurfaceCapabilitiesKHR` struct. +`vk::SurfaceCapabilitiesKHR` struct. [,c++] ---- -auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( surface ); +auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); ---- -This function takes the specified `VkPhysicalDevice` and `VkSurfaceKHR` window -surface into account when determining the supported capabilities. All the -support querying functions have these two as first parameters because they are -the core components of the swap chain. +This function takes the specified `vk::SurfaceKHR` window surface into account +when determining the supported capabilities. All the support querying functions +have that as the first parameter because it is the core component of the swap chain. The next step is about querying the supported surface formats. @@ -104,10 +108,8 @@ The next step is about querying the supported surface formats. std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR( surface ); ---- -Make sure that the vector is resized to hold all the available formats. - Finally, querying the supported presentation modes works exactly the same way -with `vkGetPhysicalDeviceSurfacePresentModesKHR`: +with `vk::raii::PhysicalDevice::getSurfacePresentModesKHR`: [,c++] ---- @@ -141,47 +143,44 @@ The function for this setting starts out like this. We'll later pass the [,c++] ---- -vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats) { - return availableFormats[0]; +vk::SurfaceFormatKHR chooseSwapSurfaceFormat(std::vector const &availableFormats) +{ + assert(!availableFormats.empty()); + return availableFormats[0]; } ---- -Each `VkSurfaceFormatKHR` entry contains a `format` and a `colorSpace` member. The +Each `vk::SurfaceFormatKHR` entry contains a `format` and a `colorSpace` member. The `format` member specifies the color channels and types. For example, -`VK_FORMAT_B8G8R8A8_SRGB` means that we store the B, G, R and alpha channels in +`vk::Format::eB8G8R8A8Srgb` means that we store the B, G, R and alpha channels in that order with an 8-bit unsigned integer for a total of 32 bits per pixel. The `colorSpace` member indicates if the SRGB color space is supported or not using -the `VK_COLOR_SPACE_SRGB_NONLINEAR_KHR` flag. Note that this flag used to be -called `VK_COLORSPACE_SRGB_NONLINEAR_KHR` in old versions of the specification. +the `vk::ColorSpaceKHR::eSrgbNonlinear` flag. For the color space we'll use SRGB if it is available, because it link:http://stackoverflow.com/questions/12524623/[results in more accurate perceived colors]. It is also pretty much the standard color space for images, like the textures we'll use later on. -Because of that we should also use an SRGB color format, of which one of the most common ones is `VK_FORMAT_B8G8R8A8_SRGB`. +Because of that we should also use an SRGB color format, of which one of the most common ones is `vk::Format::eB8G8R8A8Srgb`. Let's go through the list and see if the preferred combination is available: [,c++] ---- -for (const auto& availableFormat : availableFormats) { - if (availableFormat.format == vk::Format::eB8G8R8A8Srgb && availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) { - return availableFormat; - } +const auto formatIt = std::ranges::find_if( + availableFormats, + [](const auto &format) { return format.format == vk::Format::eB8G8R8A8Srgb && format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear; }); } ---- -If that also fails, then we could start ranking the available formats based on +If that fails, then we could start ranking the available formats based on how "good" they are, but in most cases it's okay to just settle with the first format that is specified. [,c++] ---- vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats) { - for (const auto& availableFormat : availableFormats) { - if (availableFormat.format == vk::Format::eB8G8R8A8Srgb && availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) { - return availableFormat; - } - } - - return availableFormats[0]; + const auto formatIt = std::ranges::find_if( + availableFormats, + [](const auto &format) { return format.format == vk::Format::eB8G8R8A8Srgb && format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear; }); + return formatIt != availableFormats.end() ? *formatIt : availableFormats[0]; } ---- @@ -191,19 +190,19 @@ The presentation mode is arguably the most important setting for the swap chain, because it represents the actual conditions for showing images to the screen. There are four possible modes available in Vulkan: -* `VK_PRESENT_MODE_IMMEDIATE_KHR`: Images submitted by your application are +* `vk::PresentModeKHR::eImmediate`: Images submitted by your application are transferred to the screen right away, which may result in tearing. -* `VK_PRESENT_MODE_FIFO_KHR`: The swap chain is a queue where the display takes +* `vk::PresentModeKHR::eFifo`: The swap chain is a queue where the display takes an image from the front of the queue when the display is refreshed, and the program inserts rendered images at the back of the queue. If the queue is full, then the program has to wait. This is most similar to vertical sync as found in modern games. The moment that the display is refreshed is known as "vertical blank". -* `VK_PRESENT_MODE_FIFO_RELAXED_KHR`: This mode only differs from the previous +* `vk::PresentModeKHR::eFifoRelaxed`: This mode only differs from the previous one if the application is late and the queue was empty at the last vertical blank. Instead of waiting for the next vertical blank, the image is transferred right away when it finally arrives. This may result in visible tearing. -* `VK_PRESENT_MODE_MAILBOX_KHR`: This is another variation of the second mode. +* `vk::PresentModeKHR::eMailbox`: This is another variation of the second mode. Instead of blocking the application when the queue is full, the images that are already queued are simply replaced with the newer ones. This mode can be used to render frames as fast as possible while still avoiding tearing, resulting in @@ -211,33 +210,34 @@ fewer latency issues than standard vertical sync. This is commonly known as "triple buffering," although the existence of three buffers alone does not necessarily mean that the framerate is unlocked. -Only the `VK_PRESENT_MODE_FIFO_KHR` mode is guaranteed to be available, so we'll +Only the `vk::PresentModeKHR::eFifo` mode is guaranteed to be available, so we'll again have to write a function that looks for the best mode that is available: [,c++] ---- -vk::PresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes) { +vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) +{ return vk::PresentModeKHR::eFifo; } ---- -I think that `VK_PRESENT_MODE_MAILBOX_KHR` is a very nice trade-off if +I think that `vk::PresentModeKHR::eMailbox` is a very nice trade-off if energy usage is not a concern. It allows us to avoid tearing while still maintaining fairly low latency by rendering new images that are as up to date as possible right until the vertical blank. On mobile devices, where energy usage is more important, you will probably want to use -`VK_PRESENT_MODE_FIFO_KHR` instead. Now, let's look through the list to see -if `VK_PRESENT_MODE_MAILBOX_KHR` is available: +`vk::PresentModeKHR::eFifo` instead. Now, let's look through the list to see +if `vk::PresentModeKHR::eMailbox` is available: [,c++] ---- -vk::PresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes) { - for (const auto& availablePresentMode : availablePresentModes) { - if (availablePresentMode == vk::PresentModeKHR::eMailbox) { - return availablePresentMode; - } - } - return vk::PresentModeKHR::eFifo; +vk::PresentModeKHR chooseSwapPresentMode(std::vector const &availablePresentModes) +{ + assert(std::ranges::any_of(availablePresentModes, [](auto presentMode) { return presentMode == vk::PresentModeKHR::eFifo; })); + return std::ranges::any_of(availablePresentModes, + [](const vk::PresentModeKHR value) { return vk::PresentModeKHR::eMailbox == value; }) ? + vk::PresentModeKHR::eMailbox : + vk::PresentModeKHR::eFifo; } ---- @@ -247,14 +247,14 @@ That leaves only one major property, for which we'll add one last function: [,c++] ---- -vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { -} +vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) +{} ---- The swap extent is the resolution of the swap chain images, and it's almost always exactly equal to the resolution of the window that we're drawing to _in pixels_ (more on that in a moment). The range of the possible resolutions is -defined in the `VkSurfaceCapabilitiesKHR` structure. Vulkan tells us to match +defined in the `vk::SurfaceCapabilitiesKHR` structure. Vulkan tells us to match the resolution of the window by setting the width and height in the `currentExtent` member. However, some window managers do allow us to differ here, and this is indicated by setting the width and height in `currentExtent` to a @@ -283,8 +283,10 @@ matching it against the minimum and maximum image extent. ... -vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { +vk::Extent2D chooseSwapExtent(vk::SurfaceCapabilitiesKHR const &capabilities) +{ + if (capabilities.currentExtent.width != std::numeric_limits::max()) + { return capabilities.currentExtent; } int width, height; @@ -322,11 +324,12 @@ void initVulkan() { } void createSwapChain() { - auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); - swapChainSurfaceFormat = chooseSwapSurfaceFormat(physicalDevice.getSurfaceFormatsKHR( *surface )); - swapChainExtent = chooseSwapExtent(surfaceCapabilities); - auto minImageCount = std::max( 3u, surfaceCapabilities.minImageCount ); - minImageCount = ( surfaceCapabilities.maxImageCount > 0 && minImageCount > surfaceCapabilities.maxImageCount ) ? surfaceCapabilities.maxImageCount : minImageCount; + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent(surfaceCapabilities); + uint32_t minImageCount = chooseSwapMinImageCount(surfaceCapabilities); + + std::vector availableFormats = physicalDevice.getSurfaceFormatsKHR(*surface); + swapChainSurfaceFormat = chooseSwapSurfaceFormat(availableFormats); } ---- @@ -350,12 +353,19 @@ uint32_t imageCount = surfaceCapabilities.minImageCount + 1; ---- We should also make sure to not exceed the maximum number of images while -doing this, where `0` is a special value that means that there is no maximum: +doing this, where `0` is a special value that means that there is no maximum, +resulting in this helper function [,c++] ---- -if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount) { - imageCount = surfaceCapabilities.maxImageCount; +uint32_t chooseSwapMinImageCount(vk::SurfaceCapabilitiesKHR const &surfaceCapabilities) +{ + auto minImageCount = std::max(3u, surfaceCapabilities.minImageCount); + if ((0 < surfaceCapabilities.maxImageCount) && (surfaceCapabilities.maxImageCount < minImageCount)) + { + minImageCount = surfaceCapabilities.maxImageCount; + } + return minImageCount; } ---- @@ -365,75 +375,68 @@ object so it is among the larger createInfo structures in Vulkan: [,c++] ---- -vk::SwapchainCreateInfoKHR swapChainCreateInfo{ - .flags = vk::SwapchainCreateFlagsKHR(), - .surface = *surface, - .minImageCount = minImageCount, - .imageFormat = swapChainSurfaceFormat.format, - .imageColorSpace = swapChainSurfaceFormat.colorSpace, - .imageExtent = swapChainExtent, - .imageArrayLayers =1, - .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, - .imageSharingMode = vk::SharingMode::eExclusive, - .preTransform = surfaceCapabilities.currentTransform, - .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, - .presentMode = chooseSwapPresentMode(physicalDevice.getSurfacePresentModesKHR( *surface )), - .clipped = true, - .oldSwapchain = nullptr +vk::SwapchainCreateInfoKHR swapChainCreateInfo{.surface = *surface, + .minImageCount = minImageCount, + .imageFormat = swapChainSurfaceFormat.format, + .imageColorSpace = swapChainSurfaceFormat.colorSpace, + .imageExtent = swapChainExtent, + .imageArrayLayers = 1, + .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, + .imageSharingMode = vk::SharingMode::eExclusive, + .preTransform = surfaceCapabilities.currentTransform, + .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, + .presentMode = chooseSwapPresentMode(availablePresentModes), + .clipped = true}; }; ---- +[,c++] +---- + .imageArrayLayers = 1, +---- + The `imageArrayLayers` specifies the number of layers each image consists of. -This is always `1` unless you are developing a stereoscopic 3D application. The -`imageUsage` bit field specifies what kind of operations we'll use the images in +This is always `1` unless you are developing a stereoscopic 3D application. + +[,c++] +---- + .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, +---- + +The `imageUsage` bit field specifies what kind of operations we'll use the images in the swap chain for. In this tutorial, we're going to render directly to them, which means that they're used as color attachment. It is also possible that you'll render images to a separate image first to perform operations like post-processing. In that case you may use a value like -`VK_IMAGE_USAGE_TRANSFER_DST_BIT` instead and use a memory operation to transfer +`vk::ImageUsageFlagBits::eTransferDst` instead and use a memory operation to transfer the rendered image to a swap chain image. [,c++] ---- -uint32_t queueFamilyIndices[] = {graphicsFamily, presentFamily}; - -if (graphicsFamily != presentFamily) { - swapChainCreateInfo.imageSharingMode = vk::SharingMode::eConcurrent; - swapChainCreateInfo.queueFamilyIndexCount = 2; - swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices; -} else { - swapChainCreateInfo.imageSharingMode = vk::SharingMode::eExclusive; - swapChainCreateInfo.queueFamilyIndexCount = 0; // Optional - swapChainCreateInfo.pQueueFamilyIndices = nullptr; // Optional -} + .imageSharingMode = vk::SharingMode::eExclusive, ---- -Next, we need to specify how to handle swap chain images that will be used -across multiple queue families. That will be the case in our application if the -graphics queue family is different from the presentation queue. We'll be drawing -on the images in the swap chain from the graphics queue and then submitting them -on the presentation queue. There are two ways to handle images that are -accessed from multiple queues: +The `imageSharingMode` specifies how to handle swap chain images that might be used +across multiple queue families. There are two ways to handle images that are accessed +from multiple queues: -* `VK_SHARING_MODE_EXCLUSIVE`: An image is owned by one queue family at a time, +* `vk::SharingMode::eExclusive`: An image is owned by one queue family at a time, and ownership must be explicitly transferred before using it in another queue family. This option offers the best performance. -* `VK_SHARING_MODE_CONCURRENT`: Images can be used across multiple queue +* `vk::SharingMode::eConcurrent`: Images can be used across multiple queue families without explicit ownership transfers. -If the queue families differ, then we'll be using the concurrent mode in this -tutorial to avoid having to do the ownership chapters, because these involve -some concepts that are better explained at a later time. Concurrent mode -requires you to specify in advance between which queue families ownership will -be shared using the `queueFamilyIndexCount` and `pQueueFamilyIndices` -parameters. If the graphics queue family and presentation queue family are the -same, which will be the case on most hardware, then we should stick to exclusive -mode. Concurrent mode requires you to specify at least two distinct -queue families. +If the queue families differ, then you could use the concurrent mode to avoid having +to do the ownership chapters, because these involve some concepts that are better +explained at a later time. Concurrent mode requires you to specify in advance between +which queue families ownership will be shared using the `queueFamilyIndexCount` and +`pQueueFamilyIndices` parameters. Concurrent mode requires you to specify at least two +distinct queue families. If the graphics queue family and presentation queue family are +the same, which will be the case on most hardware, then we should stick to exclusive mode. [,c++] ---- -swapChainCreateInfo.preTransform = surfaceCapabilities.currentTransform; + .preTransform = surfaceCapabilities.currentTransform, ---- We can specify that a certain transform should be applied to images in the swap @@ -443,28 +446,28 @@ any transformation, simply specify the current transformation. [,c++] ---- -swapChainCreateInfo.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque; + .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, ---- The `compositeAlpha` field specifies if the alpha channel should be used for blending with other windows in the window system. You'll almost always want to -simply ignore the alpha channel, hence `VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR`. +simply ignore the alpha channel, hence `vk::CompositeAlphaFlagBitsKHR::eOpaque`. [,c++] ---- -swapChainCreateInfo.presentMode = presentMode; -swapChainCreateInfo.clipped = vk::True; + .presentMode = chooseSwapPresentMode(availablePresentModes), + .clipped = true}; ---- The `presentMode` member speaks for itself. If the `clipped` member is set to -`VK_TRUE` then that means that we don't care about the color of pixels that are +`vk::True` then that means that we don't care about the color of pixels that are obscured, for example, because another window is in front of them. Unless you really need to be able to read these pixels back and get predictable results, you'll get the best performance by enabling clipping. [,c++] ---- -swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE; +swapChainCreateInfo.oldSwapchain = nullptr; ---- That leaves one last field, `oldSwapChain`. With Vulkan, it's possible that @@ -472,27 +475,27 @@ your swap chain becomes invalid or unoptimized while your application is running, for example, because the window was resized. In that case, the swap chain actually needs to be recreated from scratch, and a reference to the old one must be specified in this field. This is a complex topic that we'll learn more about -in xref:03_Drawing_a_triangle/04_Swap_chain_recreation.adoc[a future chapter]. For now, we'll assume that we'll only ever create -one swap chain. +in xref:03_Drawing_a_triangle/04_Swap_chain_recreation.adoc[a future chapter]. +For now, we'll assume that we'll only ever create one swap chain and can leave this +member to its default `nullptr`. -Now add class members to store the `VkSwapchainKHR` object and its images: +Now add class members to store the `vk::SwapchainKHR` object and its images: [,c++] ---- -VkSwapchainKHR swapChain; +vk::raii::SwapchainKHR swapChain; std::vector swapChainImages; ---- -Creating the swap chain is now as simple as calling `vkCreateSwapchainKHR`: +Creating the swap chain is now as simple as calling the constructor of `vk::raii::SwapchainKHR`: [,c++] ---- -swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); +swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); ---- -The parameters are the logical device, swap chain creation info, optional custom -allocators and a pointer to the variable to store the handle in. +The parameters are the logical device and a swap chain creation info. Now run the application to ensure that the swap chain is created successfully! If at this point you get an access violation error in @@ -508,12 +511,12 @@ image::/images/swap_chain_validation_layer.png[] == Retrieving the swap chain images The swap chain has been created now, so all that remains is retrieving the -handles of the `VkImage` objects it contains. We'll reference these during rendering +handles of the `vk::Image` objects it contains. We'll reference these during rendering operations in later chapters. [,c++] ---- -std::vector swapChainImages = swapChainImages = swapChain->getImages(); +std::vector swapChainImages = swapChain->getImages(); ---- One last thing, store the format and extent we've chosen for the swap chain @@ -523,13 +526,8 @@ images in member variables. We'll need them in future chapters. ---- vk::raii::SwapchainKHR swapChain = nullptr; std::vector swapChainImages; -vk::Format swapChainImageFormat = vk::Format::eUndefined; -vk::Extent2D swapChainExtent; - -... - -swapChainImageFormat = surfaceFormat.format; -swapChainExtent = extent; +vk::SurfaceFormatKHR swapChainSurfaceFormat; +vk::Extent2D swapChainExtent; ---- We now have a set of images that can be drawn onto and can be presented to the