16{
19
21
23 ? window_config.surface_format.value()
25
27
29 ? window_config.present_mode.value()
30 : surface_info.present_mode;
31
32 uint32_t desired_image_count = surface_info.image_count;
33
36
37 SwapchainSupportDetails support =
query_support(physical_device, surface);
38
39 if (!support.is_adequate()) {
41 "Swapchain support inadequate (formats: {}, modes: {})",
42 support.formats.size(), support.present_modes.size());
43 return false;
44 }
45
46 vk::SurfaceFormatKHR surface_format;
47
48 if (surface_info.enable_hdr) {
50
51 if (hdr_format.has_value()) {
52 surface_format = hdr_format.value();
53 } else {
55 "HDR requested but no HDR-capable format/colorspace supported by device/surface. Falling back to default.");
56
58 }
59
60 } else {
62 }
63
65 "Chosen swapchain format: {}, color space: {}",
66 vk::to_string(surface_format.format),
67 vk::to_string(surface_format.colorSpace));
68
70 support.present_modes, desired_present_mode);
71 vk::Extent2D extent =
choose_extent(support.capabilities, window_config.width, window_config.height);
72
73 uint32_t image_count = std::max(desired_image_count, support.capabilities.minImageCount);
74 if (support.capabilities.maxImageCount > 0) {
75 image_count = std::min(image_count, support.capabilities.maxImageCount);
76 }
77
78 vk::SwapchainCreateInfoKHR create_info {};
79 create_info.surface = surface;
80 create_info.minImageCount = image_count;
81 create_info.imageFormat = surface_format.format;
82 create_info.imageColorSpace = surface_format.colorSpace;
83 create_info.imageExtent = extent;
84 create_info.imageArrayLayers = 1;
85 create_info.imageUsage = vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst;
86
88
89 std::vector<uint32_t> queue_family_indices;
91 uint32_t present_family = queue_families.present_family.value();
92
93 if (graphics_family != present_family) {
94 queue_family_indices = { graphics_family, present_family };
95 create_info.imageSharingMode = vk::SharingMode::eConcurrent;
96 create_info.queueFamilyIndexCount = static_cast<uint32_t>(queue_family_indices.size());
97 create_info.pQueueFamilyIndices = queue_family_indices.data();
98 } else {
99 create_info.imageSharingMode = vk::SharingMode::eExclusive;
100 create_info.queueFamilyIndexCount = 0;
101 create_info.pQueueFamilyIndices = nullptr;
102 }
103
104 create_info.preTransform = support.capabilities.currentTransform;
105 create_info.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque;
106 create_info.presentMode = present_mode;
107 create_info.clipped = VK_TRUE;
108 create_info.oldSwapchain = nullptr;
109
110 try {
111 m_swapchain = device.createSwapchainKHR(create_info);
112 } catch (const vk::SystemError& e) {
114 "Failed to create swapchain: {}", e.what());
115 return false;
116 }
117
119
122
124
127 return false;
128 }
129
131 "Swapchain created: {}x{}, {} images, format {}",
132 extent.width, extent.height,
m_images.size(),
133 vk::to_string(surface_format.format));
134
135 return true;
136}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
vk::Device get_device() const
Get logical device.
const GraphicsSurfaceInfo & get_surface_info() const
Get graphics surface info.
vk::PhysicalDevice get_physical_device() const
Get physical device.
const QueueFamilyIndices & get_queue_families() const
Get queue family indices.
vk::Extent2D choose_extent(const vk::SurfaceCapabilitiesKHR &capabilities, uint32_t width, uint32_t height) const
Choose swap extent based on capabilities.
vk::PresentModeKHR choose_present_mode(const std::vector< vk::PresentModeKHR > &available_modes, GraphicsSurfaceInfo::PresentMode desired_mode) const
Choose best present mode from available modes based on config.
bool create_image_views()
Create image views for swapchain images.
vk::Format m_image_format
static SwapchainSupportDetails query_support(vk::PhysicalDevice physical_device, vk::SurfaceKHR surface)
Query swapchain support details for a device.
std::optional< vk::SurfaceFormatKHR > find_hdr_format(const std::vector< vk::SurfaceFormatKHR > &available_formats) const
Find an HDR-capable format from available formats.
vk::SurfaceFormatKHR choose_surface_format(const std::vector< vk::SurfaceFormatKHR > &available_formats, GraphicsSurfaceInfo::SurfaceFormat desired_format, GraphicsSurfaceInfo::ColorSpace desired_color_space) const
Choose best surface format from available formats based on config.
void cleanup_swapchain()
Cleanup old swapchain during recreation.
std::vector< vk::Image > m_images
const WindowCreateInfo * m_window_config
vk::SwapchainKHR m_swapchain
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.
ColorSpace
Default color space for window surfaces.
SurfaceFormat
Default pixel format for window surfaces (Vulkan-compatible)
PresentMode
Frame presentation strategy.
SurfaceFormat format
Default surface format for new windows.
std::optional< uint32_t > graphics_family