From edb3b64677a3b59930eb28849fade17d23f7b929 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 02:38:32 -0700 Subject: [PATCH 1/9] WIP in refactoring vk::physical_device API --- .../17-buffer-device-address/application.cpp | 21 +++--- vulkan-cpp/instance.cppm | 56 ++++++++++++++- vulkan-cpp/physical_device.cppm | 69 ++++++------------- 3 files changed, 87 insertions(+), 59 deletions(-) diff --git a/demos/17-buffer-device-address/application.cpp b/demos/17-buffer-device-address/application.cpp index 4ddc950..a1aab50 100644 --- a/demos/17-buffer-device-address/application.cpp +++ b/demos/17-buffer-device-address/application.cpp @@ -22,8 +22,7 @@ import vk; #include #define GLM_ENABLE_EXPERIMENTAL #include - -#include +#include #include @@ -301,13 +300,16 @@ main() { } // setting up physical device - vk::physical_enumeration enumerate_devices{ - .device_type = vk::physical_gpu::integrated, - }; - vk::physical_device physical_device(api_instance, enumerate_devices); + // vk::physical_enumeration enumerate_devices{ + // .device_type = vk::physical_gpu::integrated, + // }; + // vk::physical_device physical_device(api_instance, enumerate_devices); + + // vk::queue_indices queue_indices = physical_device.family_indices(); - vk::queue_indices queue_indices = physical_device.family_indices(); + std::expected physical_device_expected = api_instance.enumerate_physical_device(vk::physical_gpu::integrated); + vk::physical_device physical_device = physical_device_expected.value(); // setting up logical device std::array priorities = { 0.f }; @@ -353,7 +355,8 @@ main() { .features = device_features.data(), .queue_priorities = priorities, .extensions = extensions, - .queue_family_index = queue_indices.graphics, + // .queue_family_index = queue_indices.graphics, + .queue_family_index = 0, }; vk::device logical_device(physical_device, logical_device_params); @@ -434,7 +437,7 @@ main() { for (size_t i = 0; i < swapchain_command_buffers.size(); i++) { vk::command_params settings = { .levels = vk::command_levels::primary, - .queue_index = enumerate_swapchain_settings.present_index, + .queue_index = 0, .flags = vk::command_pool_flags::reset, }; diff --git a/vulkan-cpp/instance.cppm b/vulkan-cpp/instance.cppm index 6769cd7..022e8d9 100644 --- a/vulkan-cpp/instance.cppm +++ b/vulkan-cpp/instance.cppm @@ -3,11 +3,13 @@ module; #include #include #include +#include export module vk:instance; -export import :types; -export import :utilities; +import :types; +import :utilities; +import :physical_device; export namespace vk { inline namespace v1 { @@ -20,6 +22,7 @@ export namespace vk { */ class instance { public: + instance() = delete; /** * @param p_config sets the application information that vulkan has * optionally. @@ -123,6 +126,8 @@ export namespace vk { #endif } + ~instance() = default; + //! @return true if a valid VkInstance [[nodiscard]] bool alive() const { return !m_instance; } @@ -131,6 +136,53 @@ export namespace vk { return m_layer_properties; } + /** + * @brief Enumerate physical devices and select specific physical + * device to report properties from. + * + * @return vk::physical_device if successful + * @return VkResult if an unexpected error occurs + * + * + * ```C++ + * + * vk::instance api_instance = ...; + * std::optional physical_device = + * api_instance.enumerate_physical_device(vk::physical_device_type::integrated); + * + * ``` + */ + std::expected enumerate_physical_device( + physical_gpu p_device_type) { + uint32_t device_count = 0; + VkResult res = vkEnumeratePhysicalDevices( + m_instance, &device_count, nullptr); + + if (res != VK_SUCCESS) { + return std::unexpected(res); + } + + std::vector physical_devices(device_count); + res = vkEnumeratePhysicalDevices( + m_instance, &device_count, physical_devices.data()); + + if (res != VK_SUCCESS) { + return std::unexpected(res); + } + + for (const auto& device : physical_devices) { + VkPhysicalDeviceProperties device_properties; + vkGetPhysicalDeviceProperties(device, &device_properties); + + if (device_properties.deviceType == + static_cast(p_device_type)) { + return physical_device(device); + } + } + + return std::unexpected(res); + } + /** * @brief returns function pointer to allow for setting debug object * name diff --git a/vulkan-cpp/physical_device.cppm b/vulkan-cpp/physical_device.cppm index 4965d1e..2553201 100644 --- a/vulkan-cpp/physical_device.cppm +++ b/vulkan-cpp/physical_device.cppm @@ -14,61 +14,35 @@ export namespace vk { inline namespace v1 { class physical_device { public: - physical_device() = default; + + physical_device() = delete("Not allowed constructing empty vk::physical_device"); + ~physical_device() = default; - physical_device( - const VkInstance& p_instance, - const physical_enumeration& p_physical_enumeration) { - m_physical_device = enumerate_physical_devices( - p_instance, p_physical_enumeration.device_type); - - if (m_physical_device == nullptr) { - return; - } + physical_device(const VkPhysicalDevice& p_physical) + : m_physical_device(p_physical) {} - m_queue_family_properties = - enumerate_queue_family_properties(m_physical_device); - - // This makes sure that we get the graphics, compute, and - // transfer queue indices from the physical queue family - // assigned - uint32_t queue_index = 0; - for (const auto& queue_family : m_queue_family_properties) { - if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { - m_queue_family_indices.graphics = queue_index; - break; - } + /** + * @brief Query for properties for queues for you specific physical + * device. + */ + [[nodiscard]] std::span + queue_family_properties() { + uint32_t queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties( + m_physical_device, &queue_family_count, nullptr); - queue_index++; - } - queue_index = 0; + std::vector queue_families(queue_family_count); - for (const auto& queue_family : m_queue_family_properties) { - if (queue_family.queueFlags & VK_QUEUE_COMPUTE_BIT) { - m_queue_family_indices.compute = queue_index; - } - queue_index++; - } - queue_index = 0; + vkGetPhysicalDeviceQueueFamilyProperties(m_physical_device, + &queue_family_count, + queue_families.data()); - for (const auto& queue_family : m_queue_family_properties) { - if (queue_family.queueFlags & VK_QUEUE_TRANSFER_BIT) { - m_queue_family_indices.transfer = queue_index; - } - queue_index++; - } - queue_index = 0; + return queue_families; } //! @return true if physical device is valid [[nodiscard]] bool alive() const { return m_physical_device; } - //! @return queue family indices for graphics, compute, and transfer - //! operations - [[nodiscard]] queue_indices family_indices() const { - return m_queue_family_indices; - } - //! @return the presentation index for the presentation queue uint32_t queue_present_index(const VkSurfaceKHR& p_surface) { uint32_t presentation_index = 0; @@ -257,9 +231,10 @@ export namespace vk { return format; } - VkPhysicalDevice enumerate_physical_devices( + VkPhysicalDevice enumerate( const VkInstance& p_instance, const physical_gpu& p_physical_device_type) { + uint32_t device_count = 0; vkEnumeratePhysicalDevices(p_instance, &device_count, nullptr); @@ -267,8 +242,6 @@ export namespace vk { return nullptr; } - // TODO: Turn this into map std::vector physical_devices(device_count); vkEnumeratePhysicalDevices( p_instance, &device_count, physical_devices.data()); From 75c4c3b4216c66a2b00b6a21e1e777ae365f0515 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 03:21:47 -0700 Subject: [PATCH 2/9] Extended vk::physical_device to have more API's to allow for querying reports for specific properties for the physical device --- .../17-buffer-device-address/application.cpp | 17 +- vulkan-cpp/instance.cppm | 12 +- vulkan-cpp/physical_device.cppm | 195 +++++++++--------- vulkan-cpp/utilities.cppm | 18 +- 4 files changed, 109 insertions(+), 133 deletions(-) diff --git a/demos/17-buffer-device-address/application.cpp b/demos/17-buffer-device-address/application.cpp index a1aab50..1ba0d6e 100644 --- a/demos/17-buffer-device-address/application.cpp +++ b/demos/17-buffer-device-address/application.cpp @@ -300,16 +300,11 @@ main() { } // setting up physical device - // vk::physical_enumeration enumerate_devices{ - // .device_type = vk::physical_gpu::integrated, - // }; - // vk::physical_device physical_device(api_instance, enumerate_devices); - // vk::queue_indices queue_indices = physical_device.family_indices(); - - - std::expected physical_device_expected = api_instance.enumerate_physical_device(vk::physical_gpu::integrated); + std::expected physical_device_expected = + api_instance.enumerate_physical_device(vk::physical_gpu::integrated); vk::physical_device physical_device = physical_device_expected.value(); + // setting up logical device std::array priorities = { 0.f }; @@ -369,9 +364,7 @@ main() { vk::swapchain_params enumerate_swapchain_settings = { .width = static_cast(width), .height = static_cast(height), - .present_index = - physical_device.family_indices() - .graphics, // presentation index just uses the graphics index + .present_index = 0, }; vk::swapchain main_swapchain(logical_device, @@ -810,6 +803,6 @@ main() { logical_device.destroy(); window_surface.destroy(); glfwDestroyWindow(window); - api_instance.destroy(); + api_instance.destruct(); return 0; } diff --git a/vulkan-cpp/instance.cppm b/vulkan-cpp/instance.cppm index 022e8d9..518a5f8 100644 --- a/vulkan-cpp/instance.cppm +++ b/vulkan-cpp/instance.cppm @@ -126,7 +126,9 @@ export namespace vk { #endif } - ~instance() = default; + ~instance() { + destruct(); + } //! @return true if a valid VkInstance [[nodiscard]] bool alive() const { return !m_instance; } @@ -147,9 +149,11 @@ export namespace vk { * ```C++ * * vk::instance api_instance = ...; - * std::optional physical_device = + * std::expected expected = * api_instance.enumerate_physical_device(vk::physical_device_type::integrated); * + * vk::physical_device physical_device = expected.value(); + * * ``` */ std::expected enumerate_physical_device( @@ -206,7 +210,9 @@ export namespace vk { operator VkInstance() const { return m_instance; } //! @brief Invokes the destruction of the VkInstance. - void destroy() {} + void destruct() { + vkDestroyInstance(m_instance, nullptr); + } private: VkInstance m_instance = nullptr; diff --git a/vulkan-cpp/physical_device.cppm b/vulkan-cpp/physical_device.cppm index 2553201..8bdccf1 100644 --- a/vulkan-cpp/physical_device.cppm +++ b/vulkan-cpp/physical_device.cppm @@ -7,20 +7,34 @@ module; export module vk:physical_device; -export import :utilities; -export import :types; +import :utilities; +import :types; export namespace vk { inline namespace v1 { class physical_device { public: - - physical_device() = delete("Not allowed constructing empty vk::physical_device"); + physical_device() = + delete("Not allowed constructing empty vk::physical_device"); ~physical_device() = default; physical_device(const VkPhysicalDevice& p_physical) : m_physical_device(p_physical) {} + /** + * @brief reports the properties of this specific physical device + * + * @return VkPhysicalDeviceProperties of the selected physical + * device + */ + [[nodiscard]] VkPhysicalDeviceProperties properties() const { + VkPhysicalDeviceProperties device_properties; + vkGetPhysicalDeviceProperties(m_physical_device, + &device_properties); + + return device_properties; + } + /** * @brief Query for properties for queues for you specific physical * device. @@ -31,43 +45,57 @@ export namespace vk { vkGetPhysicalDeviceQueueFamilyProperties( m_physical_device, &queue_family_count, nullptr); - std::vector queue_families(queue_family_count); + m_queue_family_properties.resize(queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(m_physical_device, - &queue_family_count, - queue_families.data()); + vkGetPhysicalDeviceQueueFamilyProperties( + m_physical_device, + &queue_family_count, + m_queue_family_properties.data()); - return queue_families; + return m_queue_family_properties; } //! @return true if physical device is valid [[nodiscard]] bool alive() const { return m_physical_device; } - //! @return the presentation index for the presentation queue - uint32_t queue_present_index(const VkSurfaceKHR& p_surface) { - uint32_t presentation_index = 0; - uint32_t compatible = false; - uint32_t i = 0; + /** + * @brief Checks if the surface has presentation supported + * + * @param p_surface to perform presentation supported check on. + * @param p_queue_index to specify the queue family index to check + * presentation is supported. + * + * @return true if presentation supported, otherwise false + * + * + * Example: + * + * ```C++ + * + * vk::physical_device physical_device = ...; + * vk::surface surface = ...; + * + * bool is_present_supported = + * physical_device.is_present_supported(surface); + * + * if(is_present_supported) { ... } + * + * ``` + */ + [[nodiscard]] uint32_t is_present_supported( + const VkSurfaceKHR& p_surface, + uint32_t p_queue_index = 0) const { + uint32_t is_compatible = false; for (const auto& queue_family : m_queue_family_properties) { - vk_check(vkGetPhysicalDeviceSurfaceSupportKHR( - m_physical_device, i, p_surface, &compatible), - "vkGetPhysicalDeviceSurfaceSupportKHR"); - - if (compatible) { - presentation_index = i; - } + vk_check( + vkGetPhysicalDeviceSurfaceSupportKHR(m_physical_device, + p_queue_index, + p_surface, + &is_compatible), + "vkGetPhysicalDeviceSurfaceSupportKHR"); } - return presentation_index; - } - - //! @return physical device memory requirements - [[nodiscard]] VkPhysicalDeviceMemoryProperties memory_properties() - const { - VkPhysicalDeviceMemoryProperties physical_memory_properties; - vkGetPhysicalDeviceMemoryProperties( - m_physical_device, &physical_memory_properties); - return physical_memory_properties; + return is_compatible; } [[nodiscard]] uint32_t memory_properties( @@ -103,28 +131,54 @@ export namespace vk { [[nodiscard]] VkFormat request_depth_format( std::span p_format_supported) { - return request_compatible_formats( + return request_formats( p_format_supported, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); } /** - * @brief Requests a format and select an arbitrary format if those - * are available to select those + * @brief Requests for compatible formats to select * * @param p_tiling is selecting arrangements of the data format * @param p_feature_flag is the bitmask selection for the image * format */ - [[nodiscard]] VkFormat request_format( + [[nodiscard]] VkFormat request_formats( std::span p_format_supported, uint32_t p_tiling, uint32_t p_feature_flag) { - return request_compatible_formats( - p_format_supported, - static_cast(p_tiling), - static_cast(p_feature_flag)); + VkFormat format = VK_FORMAT_UNDEFINED; + VkImageTiling tiling = static_cast(p_tiling); + VkFormatFeatureFlags feature_flag = + static_cast(p_feature_flag); + + for (uint32_t i = 0; i < p_format_supported.size(); i++) { + VkFormat current = + static_cast(p_format_supported[i]); + VkFormatProperties format_properties; + vkGetPhysicalDeviceFormatProperties( + m_physical_device, current, &format_properties); + + switch (tiling) { + case VK_IMAGE_TILING_LINEAR: + if (format_properties.linearTilingFeatures & + feature_flag) { + format = current; + } + break; + case VK_IMAGE_TILING_OPTIMAL: + if (format_properties.optimalTilingFeatures & + feature_flag) { + format = current; + } + break; + default: + break; + } + } + + return format; } [[nodiscard]] surface_params request_surface( @@ -197,69 +251,6 @@ export namespace vk { return final_image_count; } - VkFormat request_compatible_formats( - std::span p_format_supported, - VkImageTiling p_tiling, - VkFormatFeatureFlags p_feature_flag) { - VkFormat format = VK_FORMAT_UNDEFINED; - - for (uint32_t i = 0; i < p_format_supported.size(); i++) { - VkFormat current = - static_cast(p_format_supported[i]); - VkFormatProperties format_properties; - vkGetPhysicalDeviceFormatProperties( - m_physical_device, current, &format_properties); - - switch (p_tiling) { - case VK_IMAGE_TILING_LINEAR: - if (format_properties.linearTilingFeatures & - p_feature_flag) { - format = current; - } - break; - case VK_IMAGE_TILING_OPTIMAL: - if (format_properties.optimalTilingFeatures & - p_feature_flag) { - format = current; - } - break; - default: - break; - } - } - - return format; - } - - VkPhysicalDevice enumerate( - const VkInstance& p_instance, - const physical_gpu& p_physical_device_type) { - - uint32_t device_count = 0; - vkEnumeratePhysicalDevices(p_instance, &device_count, nullptr); - - if (device_count == 0) { - return nullptr; - } - - std::vector physical_devices(device_count); - vkEnumeratePhysicalDevices( - p_instance, &device_count, physical_devices.data()); - VkPhysicalDevice physical_device = nullptr; - - for (const auto& device : physical_devices) { - VkPhysicalDeviceProperties device_properties; - vkGetPhysicalDeviceProperties(device, &device_properties); - - if (device_properties.deviceType == - static_cast( - p_physical_device_type)) { - physical_device = device; - } - } - return physical_device; - } - private: VkPhysicalDevice m_physical_device = nullptr; std::vector m_queue_family_properties; diff --git a/vulkan-cpp/utilities.cppm b/vulkan-cpp/utilities.cppm index b1f4957..496d198 100644 --- a/vulkan-cpp/utilities.cppm +++ b/vulkan-cpp/utilities.cppm @@ -9,7 +9,7 @@ module; export module vk:utilities; -export import :types; +import :types; export namespace vk { inline namespace v1 { @@ -21,21 +21,7 @@ export namespace vk { static_cast(p_result)); } } - - std::vector enumerate_queue_family_properties( - const VkPhysicalDevice& p_physical) { - uint32_t queue_family_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties( - p_physical, &queue_family_count, nullptr); - std::vector queue_family_properties( - queue_family_count); - - vkGetPhysicalDeviceQueueFamilyProperties( - p_physical, &queue_family_count, queue_family_properties.data()); - - return queue_family_properties; - } - + VkSemaphore create_semaphore(const VkDevice& p_device) { // creating semaphores VkSemaphoreCreateInfo semaphore_ci = { From 4d268d3c7c6976abf6099757db88631a6c1b5dfb Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 16:51:43 -0700 Subject: [PATCH 3/9] Extended physical_device with additional APIs --- demos/17-buffer-device-address/application.cpp | 2 +- vulkan-cpp/instance.cppm | 8 ++++---- vulkan-cpp/physical_device.cppm | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/demos/17-buffer-device-address/application.cpp b/demos/17-buffer-device-address/application.cpp index 1ba0d6e..9e5ec9f 100644 --- a/demos/17-buffer-device-address/application.cpp +++ b/demos/17-buffer-device-address/application.cpp @@ -803,6 +803,6 @@ main() { logical_device.destroy(); window_surface.destroy(); glfwDestroyWindow(window); - api_instance.destruct(); + // api_instance.destruct(); return 0; } diff --git a/vulkan-cpp/instance.cppm b/vulkan-cpp/instance.cppm index 518a5f8..80a1c6f 100644 --- a/vulkan-cpp/instance.cppm +++ b/vulkan-cpp/instance.cppm @@ -126,9 +126,7 @@ export namespace vk { #endif } - ~instance() { - destruct(); - } + ~instance() = default; //! @return true if a valid VkInstance [[nodiscard]] bool alive() const { return !m_instance; } @@ -211,7 +209,9 @@ export namespace vk { //! @brief Invokes the destruction of the VkInstance. void destruct() { - vkDestroyInstance(m_instance, nullptr); + if (m_instance != nullptr) { + vkDestroyInstance(m_instance, nullptr); + } } private: diff --git a/vulkan-cpp/physical_device.cppm b/vulkan-cpp/physical_device.cppm index 8bdccf1..b739c53 100644 --- a/vulkan-cpp/physical_device.cppm +++ b/vulkan-cpp/physical_device.cppm @@ -16,11 +16,12 @@ export namespace vk { public: physical_device() = delete("Not allowed constructing empty vk::physical_device"); - ~physical_device() = default; physical_device(const VkPhysicalDevice& p_physical) : m_physical_device(p_physical) {} + ~physical_device() = default; + /** * @brief reports the properties of this specific physical device * From ce1d9e41d3ca876fe247b73b201d730c386804d6 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 17:02:38 -0700 Subject: [PATCH 4/9] Minor code cleanup and vk::instance default construct reports deleted constructor reasoning --- vulkan-cpp/instance.cppm | 38 +++++++++++++++++++------------------- vulkan-cpp/swapchain.cppm | 4 ---- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/vulkan-cpp/instance.cppm b/vulkan-cpp/instance.cppm index 80a1c6f..e81fe38 100644 --- a/vulkan-cpp/instance.cppm +++ b/vulkan-cpp/instance.cppm @@ -22,7 +22,8 @@ export namespace vk { */ class instance { public: - instance() = delete; + instance() = delete("Disallow constructing empty vk::instance"); + /** * @param p_config sets the application information that vulkan has * optionally. @@ -47,23 +48,6 @@ export namespace vk { .pApplicationInfo = &app_info }; - // Setting up validation layers properties - uint32_t layer_count = 0; - std::vector layer_properties; - vkEnumerateInstanceLayerProperties(&layer_count, nullptr); - // std::vector layer_properties(layer_count); - layer_properties.resize(layer_count); - vkEnumerateInstanceLayerProperties(&layer_count, - layer_properties.data()); - - for (const VkLayerProperties property : layer_properties) { - m_layer_properties.emplace_back( - property.layerName, - property.specVersion, - property.implementationVersion, - property.description); - } - // Setting up instance extensions instance_ci.enabledExtensionCount = static_cast(p_config.extensions.size()); @@ -131,8 +115,24 @@ export namespace vk { //! @return true if a valid VkInstance [[nodiscard]] bool alive() const { return !m_instance; } - //! @return available validation layers + //! @return Requesting available validation layers std::span validation() { + uint32_t layer_count = 0; + std::vector layer_properties; + vkEnumerateInstanceLayerProperties(&layer_count, nullptr); + + layer_properties.resize(layer_count); + vkEnumerateInstanceLayerProperties(&layer_count, + layer_properties.data()); + + for (const VkLayerProperties property : layer_properties) { + m_layer_properties.emplace_back( + property.layerName, + property.specVersion, + property.implementationVersion, + property.description); + } + return m_layer_properties; } diff --git a/vulkan-cpp/swapchain.cppm b/vulkan-cpp/swapchain.cppm index 74d8c15..80c9976 100644 --- a/vulkan-cpp/swapchain.cppm +++ b/vulkan-cpp/swapchain.cppm @@ -1,7 +1,6 @@ module; #include -#include #include #include #include @@ -25,8 +24,6 @@ export namespace vk { , m_surface_params(p_surface_properties) { m_image_size = m_surface_params.image_size; - std::println("Surface Image Size = {}", m_image_size); - create(p_settings); } @@ -58,7 +55,6 @@ export namespace vk { VkResult res = vkCreateSwapchainKHR( m_device, &swapchain_ci, nullptr, &m_swapchain_handler); - std::println("VkResult = {}", static_cast(res)); vk_check(res, "vkCreateSwapchainKHR"); } From 89734465f64485b25c8c48cb9d4916b291ed4935 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 17:40:32 -0700 Subject: [PATCH 5/9] Minor code cleanup in vk::swapchain --- vulkan-cpp/swapchain.cppm | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/vulkan-cpp/swapchain.cppm b/vulkan-cpp/swapchain.cppm index 80c9976..28d79ff 100644 --- a/vulkan-cpp/swapchain.cppm +++ b/vulkan-cpp/swapchain.cppm @@ -13,6 +13,7 @@ export import :device_queue; export namespace vk { inline namespace v1 { + class swapchain { public: swapchain(const VkDevice& p_device, @@ -20,25 +21,25 @@ export namespace vk { const swapchain_params& p_settings, const surface_params& p_surface_properties) : m_device(p_device) - , m_surface_handler(p_surface) - , m_surface_params(p_surface_properties) { - m_image_size = m_surface_params.image_size; + , m_surface_handler(p_surface) { - create(p_settings); + construct(p_settings, p_surface_properties); } - void create(const swapchain_params& p_settings) { + void construct(const swapchain_params& p_settings, + const surface_params& p_surface_properties) { VkSwapchainCreateInfoKHR swapchain_ci = { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, .pNext = nullptr, .surface = m_surface_handler, - .minImageCount = m_image_size, - .imageFormat = m_surface_params.format.format, - .imageColorSpace = m_surface_params.format.colorSpace, + .minImageCount = p_surface_properties.image_size, + .imageFormat = p_surface_properties.format.format, + .imageColorSpace = p_surface_properties.format.colorSpace, // use physical device surface formats to getting the right // formats in vulkan - .imageExtent = m_surface_params.capabilities.currentExtent, + .imageExtent = + p_surface_properties.capabilities.currentExtent, .imageArrayLayers = 1, // Remove COLOR_ATTACHMENT flag because its not needed @@ -46,7 +47,7 @@ export namespace vk { .queueFamilyIndexCount = 0, .pQueueFamilyIndices = nullptr, .preTransform = - m_surface_params.capabilities.currentTransform, + p_surface_properties.capabilities.currentTransform, .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, .presentMode = static_cast(p_settings.present_mode), @@ -71,6 +72,7 @@ export namespace vk { * std::span images = main_swapchain.get_images(); * * ``` + * TODO: Have this return std::span * */ std::span get_images() { @@ -99,11 +101,6 @@ export namespace vk { VkDevice m_device = nullptr; VkSwapchainKHR m_swapchain_handler = nullptr; VkSurfaceKHR m_surface_handler = nullptr; - surface_params m_surface_params{}; - uint32_t m_image_size = 0; - - device_queue m_present_queue; - std::vector m_images; }; }; From 0432c8e916b28254372e02d806fe83d8e9091816 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 17:45:30 -0700 Subject: [PATCH 6/9] Deleted default constructor and added defaulted destructor to vk::swapchain --- vulkan-cpp/swapchain.cppm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vulkan-cpp/swapchain.cppm b/vulkan-cpp/swapchain.cppm index 28d79ff..28051d5 100644 --- a/vulkan-cpp/swapchain.cppm +++ b/vulkan-cpp/swapchain.cppm @@ -16,6 +16,8 @@ export namespace vk { class swapchain { public: + swapchain() = delete("Cannot construct empty swapchain"); + swapchain(const VkDevice& p_device, const VkSurfaceKHR& p_surface, const swapchain_params& p_settings, @@ -26,6 +28,8 @@ export namespace vk { construct(p_settings, p_surface_properties); } + ~swapchain() = default; + void construct(const swapchain_params& p_settings, const surface_params& p_surface_properties) { From 0548332c8207ef3dcb351b3e76c81788f075f5e0 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 17:48:14 -0700 Subject: [PATCH 7/9] Removed unneeded std::print statement --- demos/17-buffer-device-address/application.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/demos/17-buffer-device-address/application.cpp b/demos/17-buffer-device-address/application.cpp index 9e5ec9f..e79f527 100644 --- a/demos/17-buffer-device-address/application.cpp +++ b/demos/17-buffer-device-address/application.cpp @@ -379,8 +379,6 @@ main() { // querying presentable images std::span images = main_swapchain.get_images(); - - std::println("span::size() = {}", images.size()); uint32_t image_count = static_cast(images.size()); // Creating Images From b6ec3abd26a45bd20c16a1992d50af737a301113 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 17:56:26 -0700 Subject: [PATCH 8/9] Formatted utilities.cppm using clang-format --- vulkan-cpp/utilities.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vulkan-cpp/utilities.cppm b/vulkan-cpp/utilities.cppm index 496d198..7805bcc 100644 --- a/vulkan-cpp/utilities.cppm +++ b/vulkan-cpp/utilities.cppm @@ -21,7 +21,7 @@ export namespace vk { static_cast(p_result)); } } - + VkSemaphore create_semaphore(const VkDevice& p_device) { // creating semaphores VkSemaphoreCreateInfo semaphore_ci = { From 6800b567790fce8ea69704d57bb90e9e443b64f1 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 21 May 2026 18:12:55 -0700 Subject: [PATCH 9/9] Commented zero_initialize_bit from memory_allocate_flags --- vulkan-cpp/types.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vulkan-cpp/types.cppm b/vulkan-cpp/types.cppm index 65681f0..1083d53 100644 --- a/vulkan-cpp/types.cppm +++ b/vulkan-cpp/types.cppm @@ -1418,7 +1418,7 @@ export namespace vk { device_address_bit = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, device_address_capture_replay_bit = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, - zero_initialize_bit = VK_MEMORY_ALLOCATE_ZERO_INITIALIZE_BIT_EXT, + // zero_initialize_bit = VK_MEMORY_ALLOCATE_ZERO_INITIALIZE_BIT_EXT, device_mask_bit_khr = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR, device_address_bit_khr = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, device_address_capture_replay_bit_khr =