diff --git a/attachments/06_swap_chain_creation.cpp b/attachments/06_swap_chain_creation.cpp index 5f668372..3fff257c 100644 --- a/attachments/06_swap_chain_creation.cpp +++ b/attachments/06_swap_chain_creation.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -49,11 +50,10 @@ class HelloTriangleApplication { vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; std::vector requiredDeviceExtension = { @@ -245,40 +245,50 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } - static vk::Format 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; + 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(std::vector const & availableFormats) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/07_image_views.cpp b/attachments/07_image_views.cpp index c43f981f..8d6e740c 100644 --- a/attachments/07_image_views.cpp +++ b/attachments/07_image_views.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -49,11 +50,10 @@ class HelloTriangleApplication { vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; std::vector requiredDeviceExtension = { @@ -246,19 +246,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -267,7 +269,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -276,22 +278,30 @@ class HelloTriangleApplication { } } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/08_graphics_pipeline.cpp b/attachments/08_graphics_pipeline.cpp index cecbccd8..c17ac744 100644 --- a/attachments/08_graphics_pipeline.cpp +++ b/attachments/08_graphics_pipeline.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -49,11 +50,10 @@ class HelloTriangleApplication { vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; std::vector requiredDeviceExtension = { @@ -247,19 +247,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -268,7 +270,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -281,22 +283,30 @@ class HelloTriangleApplication { } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/09_shader_modules.cpp b/attachments/09_shader_modules.cpp index 09816eb5..44c02678 100644 --- a/attachments/09_shader_modules.cpp +++ b/attachments/09_shader_modules.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -50,11 +51,10 @@ class HelloTriangleApplication { vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; std::vector requiredDeviceExtension = { @@ -248,19 +248,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -269,7 +271,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -293,22 +295,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/10_fixed_functions.cpp b/attachments/10_fixed_functions.cpp index d0af79d4..7b1ca2d6 100644 --- a/attachments/10_fixed_functions.cpp +++ b/attachments/10_fixed_functions.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -50,11 +51,10 @@ class HelloTriangleApplication { vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -250,19 +250,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -271,7 +273,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -322,22 +324,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/12_graphics_pipeline_complete.cpp b/attachments/12_graphics_pipeline_complete.cpp index 70279ee5..21444daf 100644 --- a/attachments/12_graphics_pipeline_complete.cpp +++ b/attachments/12_graphics_pipeline_complete.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -50,11 +51,10 @@ class HelloTriangleApplication { vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -251,19 +251,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -272,7 +274,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -315,7 +317,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -333,22 +335,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/14_command_buffers.cpp b/attachments/14_command_buffers.cpp index f0d24467..00c9b90a 100644 --- a/attachments/14_command_buffers.cpp +++ b/attachments/14_command_buffers.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -51,11 +52,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -255,19 +255,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -276,7 +278,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -319,7 +321,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -429,22 +431,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/15_hello_triangle.cpp b/attachments/15_hello_triangle.cpp index eedf7ef5..2b1ea167 100644 --- a/attachments/15_hello_triangle.cpp +++ b/attachments/15_hello_triangle.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -51,11 +52,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -264,19 +264,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -285,7 +287,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -328,7 +330,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -471,22 +473,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/16_frames_in_flight.cpp b/attachments/16_frames_in_flight.cpp index 35dedd6c..d98a8031 100644 --- a/attachments/16_frames_in_flight.cpp +++ b/attachments/16_frames_in_flight.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -52,11 +53,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -268,19 +268,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -289,7 +291,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -332,7 +334,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -487,22 +489,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/17_swap_chain_recreation.cpp b/attachments/17_swap_chain_recreation.cpp index e2dd5893..94e1f581 100644 --- a/attachments/17_swap_chain_recreation.cpp +++ b/attachments/17_swap_chain_recreation.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -52,11 +53,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -295,19 +295,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -316,7 +318,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -359,7 +361,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -523,22 +525,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/18_vertex_input.cpp b/attachments/18_vertex_input.cpp index 3412319b..e8dd513e 100644 --- a/attachments/18_vertex_input.cpp +++ b/attachments/18_vertex_input.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -76,11 +77,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -319,19 +319,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -340,7 +342,7 @@ class HelloTriangleApplication { void createImageViews() { swapChainImageViews.clear(); - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -386,7 +388,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -550,22 +552,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/19_vertex_buffer.cpp b/attachments/19_vertex_buffer.cpp index 2a427649..48032fd1 100644 --- a/attachments/19_vertex_buffer.cpp +++ b/attachments/19_vertex_buffer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -76,11 +77,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -323,26 +323,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -388,7 +390,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -580,22 +582,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/20_staging_buffer.cpp b/attachments/20_staging_buffer.cpp index 85023fef..7618e174 100644 --- a/attachments/20_staging_buffer.cpp +++ b/attachments/20_staging_buffer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -76,11 +77,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -323,26 +323,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -388,7 +390,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -599,22 +601,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/21_index_buffer.cpp b/attachments/21_index_buffer.cpp index acae477f..7eab95c6 100644 --- a/attachments/21_index_buffer.cpp +++ b/attachments/21_index_buffer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -81,11 +82,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -331,26 +331,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -396,7 +398,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -624,22 +626,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/22_descriptor_layout.cpp b/attachments/22_descriptor_layout.cpp index f0800e1e..4eb2bdd5 100644 --- a/attachments/22_descriptor_layout.cpp +++ b/attachments/22_descriptor_layout.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -91,11 +92,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -348,26 +348,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -419,7 +421,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -679,22 +681,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/23_descriptor_sets.cpp b/attachments/23_descriptor_sets.cpp index 5a734b75..03add3f2 100644 --- a/attachments/23_descriptor_sets.cpp +++ b/attachments/23_descriptor_sets.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -91,11 +92,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -353,26 +353,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -424,7 +426,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -704,22 +706,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/24_texture_image.cpp b/attachments/24_texture_image.cpp index 0c516081..901bfdcc 100644 --- a/attachments/24_texture_image.cpp +++ b/attachments/24_texture_image.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -94,11 +95,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -360,26 +360,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -431,7 +433,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -808,22 +810,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/25_sampler.cpp b/attachments/25_sampler.cpp index 3bcd184a..af435325 100644 --- a/attachments/25_sampler.cpp +++ b/attachments/25_sampler.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -94,11 +95,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -365,26 +365,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -436,7 +438,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -843,22 +845,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/26_texture_mapping.cpp b/attachments/26_texture_mapping.cpp index 9f50edd2..16fc5cc2 100644 --- a/attachments/26_texture_mapping.cpp +++ b/attachments/26_texture_mapping.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -96,11 +97,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -367,26 +367,28 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); } void createImageViews() { - vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainImageFormat, + vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) { @@ -442,7 +444,7 @@ class HelloTriangleApplication { pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, .pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly, @@ -920,22 +922,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/27_depth_buffering.cpp b/attachments/27_depth_buffering.cpp index 97f2d987..248345df 100644 --- a/attachments/27_depth_buffering.cpp +++ b/attachments/27_depth_buffering.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -103,11 +104,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -380,19 +380,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -401,7 +403,7 @@ class HelloTriangleApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) @@ -488,7 +490,7 @@ class HelloTriangleApplication { vk::Format depthFormat = findDepthFormat(); vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, - .pColorAttachmentFormats = &swapChainImageFormat, + .pColorAttachmentFormats = &swapChainSurfaceFormat.format, .depthAttachmentFormat = depthFormat }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, @@ -1048,22 +1050,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/28_model_loading.cpp b/attachments/28_model_loading.cpp index 76e9e177..791a6539 100644 --- a/attachments/28_model_loading.cpp +++ b/attachments/28_model_loading.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -104,11 +105,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -384,19 +384,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -405,7 +407,7 @@ class HelloTriangleApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) @@ -492,7 +494,7 @@ class HelloTriangleApplication { vk::Format depthFormat = findDepthFormat(); vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, - .pColorAttachmentFormats = &swapChainImageFormat, + .pColorAttachmentFormats = &swapChainSurfaceFormat.format, .depthAttachmentFormat = depthFormat }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, @@ -1093,22 +1095,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/29_mipmapping.cpp b/attachments/29_mipmapping.cpp index 07abbc05..6f941097 100644 --- a/attachments/29_mipmapping.cpp +++ b/attachments/29_mipmapping.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -104,11 +105,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -384,19 +384,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -405,7 +407,7 @@ class HelloTriangleApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) @@ -492,7 +494,7 @@ class HelloTriangleApplication { vk::Format depthFormat = findDepthFormat(); vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, - .pColorAttachmentFormats = &swapChainImageFormat, + .pColorAttachmentFormats = &swapChainSurfaceFormat.format, .depthAttachmentFormat = depthFormat }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, @@ -1159,22 +1161,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) const { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/30_multisampling.cpp b/attachments/30_multisampling.cpp index 99b48cda..ed8132fb 100644 --- a/attachments/30_multisampling.cpp +++ b/attachments/30_multisampling.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -105,11 +106,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -393,19 +393,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -414,7 +416,7 @@ class HelloTriangleApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) @@ -501,7 +503,7 @@ class HelloTriangleApplication { vk::Format depthFormat = findDepthFormat(); vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, - .pColorAttachmentFormats = &swapChainImageFormat, + .pColorAttachmentFormats = &swapChainSurfaceFormat.format, .depthAttachmentFormat = depthFormat }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, @@ -531,7 +533,7 @@ class HelloTriangleApplication { } void createColorResources() { - vk::Format colorFormat = swapChainImageFormat; + vk::Format colorFormat = swapChainSurfaceFormat.format; createImage(swapChainExtent.width, swapChainExtent.height, 1, msaaSamples, colorFormat, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eTransientAttachment | vk::ImageUsageFlagBits::eColorAttachment, vk::MemoryPropertyFlagBits::eDeviceLocal, colorImage, colorImageMemory); colorImageView = createImageView(colorImage, colorFormat, vk::ImageAspectFlagBits::eColor, 1); @@ -1231,22 +1233,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format 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; + 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) { + 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) { + 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; } [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) const { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/31_compute_shader.cpp b/attachments/31_compute_shader.cpp index 5cfafd85..420dad15 100644 --- a/attachments/31_compute_shader.cpp +++ b/attachments/31_compute_shader.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -86,11 +87,10 @@ class ComputeShaderApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::SurfaceFormatKHR swapChainImageFormat; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -372,20 +372,21 @@ class ComputeShaderApplication { } 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{ - .flags = vk::SwapchainCreateFlagsKHR(), - .surface = surface, .minImageCount = minImageCount, - .imageFormat = swapChainImageFormat.format, .imageColorSpace = swapChainImageFormat.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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR( device, swapChainCreateInfo ); swapChainImages = swapChain.getImages(); @@ -394,7 +395,7 @@ class ComputeShaderApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat.format, + .format = swapChainSurfaceFormat.format, .components = {vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity}, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; @@ -463,7 +464,7 @@ class ComputeShaderApplication { vk::PipelineLayoutCreateInfo pipelineLayoutInfo; pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat.format }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, @@ -879,27 +880,30 @@ class ComputeShaderApplication { return shaderModule; } - static 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; - } + 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; + } - return availableFormats[0]; + static vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats) { + 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) { - for (const auto& availablePresentMode : availablePresentModes) { - if (availablePresentMode == vk::PresentModeKHR::eMailbox) { - return availablePresentMode; - } - } - return vk::PresentModeKHR::eFifo; + 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; } [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) const { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/32_ecosystem_utilities.cpp b/attachments/32_ecosystem_utilities.cpp index 8375ad05..18f9e914 100644 --- a/attachments/32_ecosystem_utilities.cpp +++ b/attachments/32_ecosystem_utilities.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -107,11 +108,10 @@ class HelloTriangleApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; // Traditional render pass (fallback for non-dynamic rendering) @@ -496,19 +496,21 @@ class HelloTriangleApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -517,7 +519,7 @@ class HelloTriangleApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) @@ -538,7 +540,7 @@ class HelloTriangleApplication { // Color attachment description vk::AttachmentDescription colorAttachment{ - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .samples = msaaSamples, .loadOp = vk::AttachmentLoadOp::eClear, .storeOp = vk::AttachmentStoreOp::eStore, @@ -560,7 +562,7 @@ class HelloTriangleApplication { }; vk::AttachmentDescription colorAttachmentResolve{ - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .samples = vk::SampleCountFlagBits::e1, .loadOp = vk::AttachmentLoadOp::eDontCare, .storeOp = vk::AttachmentStoreOp::eStore, @@ -743,7 +745,7 @@ class HelloTriangleApplication { if (appInfo.dynamicRenderingSupported) { std::cout << "Configuring pipeline for dynamic rendering\n"; pipelineRenderingCreateInfo.colorAttachmentCount = 1; - pipelineRenderingCreateInfo.pColorAttachmentFormats = &swapChainImageFormat; + pipelineRenderingCreateInfo.pColorAttachmentFormats = &swapChainSurfaceFormat.format; pipelineRenderingCreateInfo.depthAttachmentFormat = findDepthFormat(); pipelineInfo.pNext = &pipelineRenderingCreateInfo; @@ -767,7 +769,7 @@ class HelloTriangleApplication { } void createColorResources() { - vk::Format colorFormat = swapChainImageFormat; + vk::Format colorFormat = swapChainSurfaceFormat.format; createImage(swapChainExtent.width, swapChainExtent.height, 1, msaaSamples, colorFormat, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eTransientAttachment | vk::ImageUsageFlagBits::eColorAttachment, vk::MemoryPropertyFlagBits::eDeviceLocal, colorImage, colorImageMemory); colorImageView = createImageView(colorImage, colorFormat, vk::ImageAspectFlagBits::eColor, 1); @@ -1608,17 +1610,30 @@ class HelloTriangleApplication { return shaderModule; } - static vk::Format chooseSwapSurfaceFormat(const std::vector& availableFormats) { - return (availableFormats[0].format == vk::Format::eUndefined) ? vk::Format::eB8G8R8A8Unorm : availableFormats[0].format; + 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) { + 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) { + 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; } [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) const { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/33_vulkan_profiles.cpp b/attachments/33_vulkan_profiles.cpp index b50975fb..4dee36c6 100644 --- a/attachments/33_vulkan_profiles.cpp +++ b/attachments/33_vulkan_profiles.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -101,13 +102,14 @@ class HelloTriangleApplication { vk::raii::SurfaceKHR surface = nullptr; vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; - uint32_t queueIndex = ~0; + uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = {}; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; + vk::raii::RenderPass renderPass = nullptr; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -471,43 +473,30 @@ class HelloTriangleApplication { void createSwapChain() { SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); - - vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); - vk::PresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); - vk::Extent2D extent = chooseSwapExtent(swapChainSupport.capabilities); - - uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; - if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { - imageCount = swapChainSupport.capabilities.maxImageCount; - } - - vk::SwapchainCreateInfoKHR createInfo{ - .surface = *surface, - .minImageCount = imageCount, - .imageFormat = surfaceFormat.format, - .imageColorSpace = surfaceFormat.colorSpace, - .imageExtent = extent, - .imageArrayLayers = 1, - .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, - .imageSharingMode = vk::SharingMode::eExclusive - }; - - createInfo.preTransform = swapChainSupport.capabilities.currentTransform; - createInfo.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque; - createInfo.presentMode = presentMode; - createInfo.clipped = VK_TRUE; - - swapChain = device.createSwapchainKHR(createInfo); + swapChainExtent = chooseSwapExtent( swapChainSupport.capabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( swapChainSupport.formats ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( swapChainSupport.capabilities ), + .imageFormat = swapChainSurfaceFormat.format, + .imageColorSpace = swapChainSurfaceFormat.colorSpace, + .imageExtent = swapChainExtent, + .imageArrayLayers = 1, + .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, + .imageSharingMode = vk::SharingMode::eExclusive, + .preTransform = swapChainSupport.capabilities.currentTransform, + .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, + .presentMode = chooseSwapPresentMode( swapChainSupport.presentModes ), + .clipped = true }; + + swapChain = device.createSwapchainKHR(swapChainCreateInfo); swapChainImages = swapChain.getImages(); - swapChainImageFormat = surfaceFormat.format; - swapChainExtent = extent; } void createImageViews() { swapChainImageViews.reserve(swapChainImages.size()); for (const auto& image : swapChainImages) { - swapChainImageViews.push_back(createImageView(image, swapChainImageFormat, vk::ImageAspectFlagBits::eColor, 1)); + swapChainImageViews.push_back(createImageView(image, swapChainSurfaceFormat.format, vk::ImageAspectFlagBits::eColor, 1)); } } @@ -515,7 +504,7 @@ class HelloTriangleApplication { // This is only called if the Best Practices profile is not supported // or if dynamic rendering is not available vk::AttachmentDescription colorAttachment{ - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .samples = msaaSamples, .loadOp = vk::AttachmentLoadOp::eClear, .storeOp = vk::AttachmentStoreOp::eStore, @@ -537,7 +526,7 @@ class HelloTriangleApplication { }; vk::AttachmentDescription colorAttachmentResolve{ - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .samples = vk::SampleCountFlagBits::e1, .loadOp = vk::AttachmentLoadOp::eDontCare, .storeOp = vk::AttachmentStoreOp::eStore, @@ -727,7 +716,7 @@ class HelloTriangleApplication { // Configure pipeline based on whether we're using the KHR roadmap 2022 profile if (appInfo.profileSupported) { // With the KHR roadmap 2022 profile, we can use dynamic rendering - vk::Format colorFormat = swapChainImageFormat; + vk::Format colorFormat = swapChainSurfaceFormat.format; vk::Format depthFormat = findDepthFormat(); vk::PipelineRenderingCreateInfo renderingInfo{ @@ -787,7 +776,7 @@ class HelloTriangleApplication { } void createColorResources() { - vk::Format colorFormat = swapChainImageFormat; + vk::Format colorFormat = swapChainSurfaceFormat.format; createImage(swapChainExtent.width, swapChainExtent.height, 1, msaaSamples, colorFormat, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eTransientAttachment | vk::ImageUsageFlagBits::eColorAttachment, vk::MemoryPropertyFlagBits::eDeviceLocal, colorImage, colorImageMemory); colorImageView = createImageView(*colorImage, colorFormat, vk::ImageAspectFlagBits::eColor, 1); @@ -1610,19 +1599,30 @@ class HelloTriangleApplication { throw std::runtime_error("failed to find suitable memory type!"); } - vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats) { - return (availableFormats[0].format == vk::Format::eUndefined) - ? vk::SurfaceFormatKHR{vk::Format::eB8G8R8A8Unorm, availableFormats[0].colorSpace} - : availableFormats[0]; + 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) { + 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]; } vk::PresentModeKHR chooseSwapPresentMode(const std::vector& 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; diff --git a/attachments/34_android.cpp b/attachments/34_android.cpp index 977c8575..a4bf7396 100644 --- a/attachments/34_android.cpp +++ b/attachments/34_android.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -299,13 +300,14 @@ class HelloTriangleApplication { vk::raii::SurfaceKHR surface = nullptr; vk::raii::PhysicalDevice physicalDevice = nullptr; vk::raii::Device device = nullptr; - uint32_t queueIndex = ~0; + uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = {}; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; + vk::raii::RenderPass renderPass = nullptr; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -589,36 +591,23 @@ class HelloTriangleApplication { // Create swap chain void createSwapChain() { SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); - - vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); - vk::PresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); - vk::Extent2D extent = chooseSwapExtent(swapChainSupport.capabilities); - - uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; - if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { - imageCount = swapChainSupport.capabilities.maxImageCount; - } - - vk::SwapchainCreateInfoKHR createInfo{ - .surface = *surface, - .minImageCount = imageCount, - .imageFormat = surfaceFormat.format, - .imageColorSpace = surfaceFormat.colorSpace, - .imageExtent = extent, - .imageArrayLayers = 1, - .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, - .imageSharingMode = vk::SharingMode::eExclusive - }; - - createInfo.preTransform = swapChainSupport.capabilities.currentTransform; - createInfo.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque; - createInfo.presentMode = presentMode; - createInfo.clipped = VK_TRUE; - - swapChain = device.createSwapchainKHR(createInfo); + swapChainExtent = chooseSwapExtent( swapChainSupport.capabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( swapChainSupport.formats ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( swapChainSupport.capabilities ), + .imageFormat = swapChainSurfaceFormat.format, + .imageColorSpace = swapChainSurfaceFormat.colorSpace, + .imageExtent = swapChainExtent, + .imageArrayLayers = 1, + .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, + .imageSharingMode = vk::SharingMode::eExclusive, + .preTransform = swapChainSupport.capabilities.currentTransform, + .compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque, + .presentMode = chooseSwapPresentMode( swapChainSupport.presentModes ), + .clipped = true }; + + swapChain = device.createSwapchainKHR(swapChainCreateInfo); swapChainImages = swapChain.getImages(); - swapChainImageFormat = surfaceFormat.format; - swapChainExtent = extent; } // Create image views @@ -629,7 +618,7 @@ class HelloTriangleApplication { vk::ImageViewCreateInfo createInfo{ .image = image, .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .components = { .r = vk::ComponentSwizzle::eIdentity, .g = vk::ComponentSwizzle::eIdentity, @@ -652,7 +641,7 @@ class HelloTriangleApplication { // Create render pass void createRenderPass() { vk::AttachmentDescription colorAttachment{ - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .samples = vk::SampleCountFlagBits::e1, .loadOp = vk::AttachmentLoadOp::eClear, .storeOp = vk::AttachmentStoreOp::eStore, @@ -1369,36 +1358,33 @@ class HelloTriangleApplication { return extensions; } - // Choose swap surface format - vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats) { - // Prefer SRGB format - for (const auto& availableFormat : availableFormats) { - if (availableFormat.format == vk::Format::eB8G8R8A8Srgb && - availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) { - return availableFormat; - } + 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; + } - // If not available, just use the first format - return availableFormats[0]; + // Choose swap surface format + vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats) { + 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]; } // Choose swap present mode vk::PresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes) { - // Prefer mailbox mode for triple buffering - for (const auto& availablePresentMode : availablePresentModes) { - if (availablePresentMode == vk::PresentModeKHR::eMailbox) { - return availablePresentMode; - } - } - - // Fallback to FIFO (guaranteed to be available) - return vk::PresentModeKHR::eFifo; + 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; } // Choose swap extent vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } else { #if PLATFORM_ANDROID diff --git a/attachments/35_gltf_ktx.cpp b/attachments/35_gltf_ktx.cpp index c2139878..b8db78b4 100644 --- a/attachments/35_gltf_ktx.cpp +++ b/attachments/35_gltf_ktx.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -247,11 +248,10 @@ class VulkanApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -566,19 +566,21 @@ class VulkanApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -587,7 +589,7 @@ class VulkanApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) @@ -671,7 +673,7 @@ class VulkanApplication { pipelineLayout = vk::raii::PipelineLayout(device, pipelineLayoutInfo); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, @@ -1328,17 +1330,30 @@ class VulkanApplication { return shaderModule; } - static vk::Format chooseSwapSurfaceFormat(const std::vector& availableFormats) { - return (availableFormats[0].format == vk::Format::eUndefined) ? vk::Format::eB8G8R8A8Unorm : availableFormats[0].format; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } #if PLATFORM_DESKTOP diff --git a/attachments/36_multiple_objects.cpp b/attachments/36_multiple_objects.cpp index 85da0542..d23221cc 100644 --- a/attachments/36_multiple_objects.cpp +++ b/attachments/36_multiple_objects.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -295,11 +296,10 @@ class VulkanApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::Format swapChainImageFormat = vk::Format::eUndefined; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr; @@ -630,19 +630,21 @@ class VulkanApplication { } 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 }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 }; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); swapChainImages = swapChain.getImages(); @@ -651,7 +653,7 @@ class VulkanApplication { void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat, + .format = swapChainSurfaceFormat.format, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; for ( auto image : swapChainImages ) @@ -735,7 +737,7 @@ class VulkanApplication { pipelineLayout = vk::raii::PipelineLayout(device, pipelineLayoutInfo); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages, @@ -1461,17 +1463,30 @@ class VulkanApplication { return shaderModule; } - static vk::Format chooseSwapSurfaceFormat(const std::vector& availableFormats) { - return (availableFormats[0].format == vk::Format::eUndefined) ? vk::Format::eB8G8R8A8Unorm : availableFormats[0].format; + 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) { + 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) { + 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; } vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } #if PLATFORM_DESKTOP diff --git a/attachments/37_multithreading.cpp b/attachments/37_multithreading.cpp index c30c4d1f..b08274c6 100644 --- a/attachments/37_multithreading.cpp +++ b/attachments/37_multithreading.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef __INTELLISENSE__ #include @@ -154,11 +155,10 @@ class MultithreadedApplication { vk::raii::Device device = nullptr; uint32_t queueIndex = ~0; vk::raii::Queue queue = nullptr; - - vk::raii::SwapchainKHR swapChain = nullptr; - std::vector swapChainImages; - vk::SurfaceFormatKHR swapChainImageFormat; - vk::Extent2D swapChainExtent; + vk::raii::SwapchainKHR swapChain = nullptr; + std::vector swapChainImages; + vk::SurfaceFormatKHR swapChainSurfaceFormat; + vk::Extent2D swapChainExtent; std::vector swapChainImageViews; vk::raii::PipelineLayout pipelineLayout = nullptr; @@ -224,25 +224,30 @@ class MultithreadedApplication { std::vector extensions(glfwExtensions, glfwExtensions + glfwExtensionCount); return extensions; } - static 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; - } + + 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; + } - return availableFormats[0]; + static vk::SurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats) { + 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) { - for (const auto& availablePresentMode : availablePresentModes) { - if (availablePresentMode == vk::PresentModeKHR::eMailbox) { - return availablePresentMode; - } - } - return vk::PresentModeKHR::eFifo; + 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; } [[nodiscard]] vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) const { - if (capabilities.currentExtent.width != std::numeric_limits::max()) { + if (capabilities.currentExtent.width != 0xFFFFFFFF) { return capabilities.currentExtent; } int width, height; @@ -581,34 +586,31 @@ class MultithreadedApplication { } 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::raii::SwapchainKHR oldSwapChain = std::move(swapChain); - - vk::SwapchainCreateInfoKHR swapChainCreateInfo{ - .flags = vk::SwapchainCreateFlagsKHR(), - .surface = surface, .minImageCount = minImageCount, - .imageFormat = swapChainImageFormat.format, .imageColorSpace = swapChainImageFormat.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 = *oldSwapChain ? *oldSwapChain : nullptr }; + auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( *surface ); + swapChainExtent = chooseSwapExtent( surfaceCapabilities ); + swapChainSurfaceFormat = chooseSwapSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( *surface ) ); + vk::SwapchainCreateInfoKHR swapChainCreateInfo{ .surface = *surface, + .minImageCount = chooseSwapMinImageCount( surfaceCapabilities ), + .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 = *swapChain ? *swapChain : nullptr }; swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo); - oldSwapChain = nullptr; swapChainImages = swapChain.getImages(); } void createImageViews() { vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, - .format = swapChainImageFormat.format, + .format = swapChainSurfaceFormat.format, .components = {vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity}, .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } }; @@ -676,7 +678,7 @@ class MultithreadedApplication { vk::PipelineLayoutCreateInfo pipelineLayoutInfo; pipelineLayout = vk::raii::PipelineLayout( device, pipelineLayoutInfo ); - vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainImageFormat.format }; + vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapChainSurfaceFormat.format }; vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo, .stageCount = 2, .pStages = shaderStages,