@@ -29,6 +29,11 @@ constexpr const T &clamp(const T &v, const T &lo, const T &hi)
2929 return (v < lo) ? lo : ((hi < v) ? hi : v);
3030}
3131
32+ inline uint32_t choose_image_count (uint32_t request_image_count, uint32_t min_image_count, uint32_t max_image_count)
33+ {
34+ return clamp (request_image_count, min_image_count, (max_image_count != 0 ) ? max_image_count : request_image_count);
35+ }
36+
3237vk::Extent2D choose_extent (vk::Extent2D request_extent,
3338 const vk::Extent2D &min_image_extent,
3439 const vk::Extent2D &max_image_extent,
@@ -111,6 +116,11 @@ vk::SurfaceFormatKHR choose_surface_format(const vk::SurfaceFormatKHR
111116 }
112117}
113118
119+ inline uint32_t choose_image_array_layers (uint32_t request_image_array_layers, uint32_t max_image_array_layers)
120+ {
121+ return clamp (request_image_array_layers, 1u , max_image_array_layers);
122+ }
123+
114124vk::SurfaceTransformFlagBitsKHR choose_transform (vk::SurfaceTransformFlagBitsKHR request_transform,
115125 vk::SurfaceTransformFlagsKHR supported_transform,
116126 vk::SurfaceTransformFlagBitsKHR current_transform)
@@ -221,7 +231,8 @@ vk::ImageUsageFlags composite_image_flags(std::set<vk::ImageUsageFlagBits> &imag
221231namespace core
222232{
223233HPPSwapchain::HPPSwapchain (HPPSwapchain &old_swapchain, const vk::Extent2D &extent) :
224- HPPSwapchain{old_swapchain.device ,
234+ HPPSwapchain{old_swapchain,
235+ old_swapchain.device ,
225236 old_swapchain.surface ,
226237 old_swapchain.properties .present_mode ,
227238 old_swapchain.present_mode_priority_list ,
@@ -230,11 +241,13 @@ HPPSwapchain::HPPSwapchain(HPPSwapchain &old_swapchain, const vk::Extent2D &exte
230241 old_swapchain.properties .image_count ,
231242 old_swapchain.properties .pre_transform ,
232243 old_swapchain.image_usage_flags ,
233- old_swapchain.get_handle ()}
244+ old_swapchain.requested_compression ,
245+ old_swapchain.requested_compression_fixed_rate }
234246{}
235247
236248HPPSwapchain::HPPSwapchain (HPPSwapchain &old_swapchain, const uint32_t image_count) :
237- HPPSwapchain{old_swapchain.device ,
249+ HPPSwapchain{old_swapchain,
250+ old_swapchain.device ,
238251 old_swapchain.surface ,
239252 old_swapchain.properties .present_mode ,
240253 old_swapchain.present_mode_priority_list ,
@@ -243,11 +256,13 @@ HPPSwapchain::HPPSwapchain(HPPSwapchain &old_swapchain, const uint32_t image_cou
243256 image_count,
244257 old_swapchain.properties .pre_transform ,
245258 old_swapchain.image_usage_flags ,
246- old_swapchain.get_handle ()}
259+ old_swapchain.requested_compression ,
260+ old_swapchain.requested_compression_fixed_rate }
247261{}
248262
249263HPPSwapchain::HPPSwapchain (HPPSwapchain &old_swapchain, const std::set<vk::ImageUsageFlagBits> &image_usage_flags) :
250- HPPSwapchain{old_swapchain.device ,
264+ HPPSwapchain{old_swapchain,
265+ old_swapchain.device ,
251266 old_swapchain.surface ,
252267 old_swapchain.properties .present_mode ,
253268 old_swapchain.present_mode_priority_list ,
@@ -256,11 +271,13 @@ HPPSwapchain::HPPSwapchain(HPPSwapchain &old_swapchain, const std::set<vk::Image
256271 old_swapchain.properties .image_count ,
257272 old_swapchain.properties .pre_transform ,
258273 image_usage_flags,
259- old_swapchain.get_handle ()}
274+ old_swapchain.requested_compression ,
275+ old_swapchain.requested_compression_fixed_rate }
260276{}
261277
262278HPPSwapchain::HPPSwapchain (HPPSwapchain &old_swapchain, const vk::Extent2D &extent, const vk::SurfaceTransformFlagBitsKHR transform) :
263- HPPSwapchain{old_swapchain.device ,
279+ HPPSwapchain{old_swapchain,
280+ old_swapchain.device ,
264281 old_swapchain.surface ,
265282 old_swapchain.properties .present_mode ,
266283 old_swapchain.present_mode_priority_list ,
@@ -269,21 +286,58 @@ HPPSwapchain::HPPSwapchain(HPPSwapchain &old_swapchain, const vk::Extent2D &exte
269286 old_swapchain.properties .image_count ,
270287 transform,
271288 old_swapchain.image_usage_flags ,
272- old_swapchain.get_handle ()}
289+ old_swapchain.requested_compression ,
290+ old_swapchain.requested_compression_fixed_rate }
291+ {}
292+
293+ HPPSwapchain::HPPSwapchain (HPPSwapchain &old_swapchain,
294+ const vk::ImageCompressionFlagsEXT requested_compression,
295+ const vk::ImageCompressionFixedRateFlagsEXT requested_compression_fixed_rate) :
296+ HPPSwapchain{old_swapchain,
297+ old_swapchain.device ,
298+ old_swapchain.surface ,
299+ old_swapchain.properties .present_mode ,
300+ old_swapchain.present_mode_priority_list ,
301+ old_swapchain.surface_format_priority_list ,
302+ old_swapchain.properties .extent ,
303+ old_swapchain.properties .image_count ,
304+ old_swapchain.properties .pre_transform ,
305+ old_swapchain.image_usage_flags ,
306+ requested_compression,
307+ requested_compression_fixed_rate}
308+ {
309+ }
310+
311+ HPPSwapchain::HPPSwapchain (vkb::core::DeviceCpp &device,
312+ vk::SurfaceKHR surface,
313+ const vk::PresentModeKHR present_mode,
314+ const std::vector<vk::PresentModeKHR> &present_mode_priority_list,
315+ const std::vector<vk::SurfaceFormatKHR> &surface_format_priority_list,
316+ const vk::Extent2D &extent,
317+ const uint32_t image_count,
318+ const vk::SurfaceTransformFlagBitsKHR transform,
319+ const std::set<vk::ImageUsageFlagBits> &image_usage_flags,
320+ const vk::ImageCompressionFlagsEXT requested_compression,
321+ const vk::ImageCompressionFixedRateFlagsEXT requested_compression_fixed_rate) :
322+ HPPSwapchain{*this , device, surface, present_mode, present_mode_priority_list, surface_format_priority_list, extent, image_count, transform, image_usage_flags}
273323{}
274324
275- HPPSwapchain::HPPSwapchain (vkb::core::DeviceCpp &device,
276- vk::SurfaceKHR surface,
277- const vk::PresentModeKHR present_mode,
278- const std::vector<vk::PresentModeKHR> &present_mode_priority_list,
279- const std::vector<vk::SurfaceFormatKHR> &surface_format_priority_list,
280- const vk::Extent2D &extent,
281- const uint32_t image_count,
282- const vk::SurfaceTransformFlagBitsKHR transform,
283- const std::set<vk::ImageUsageFlagBits> &image_usage_flags,
284- vk::SwapchainKHR old_swapchain) :
325+ HPPSwapchain::HPPSwapchain (HPPSwapchain &old_swapchain,
326+ vkb::core::DeviceCpp &device,
327+ vk::SurfaceKHR surface,
328+ const vk::PresentModeKHR present_mode,
329+ std::vector<vk::PresentModeKHR> const &present_mode_priority_list,
330+ const std::vector<vk::SurfaceFormatKHR> &surface_format_priority_list,
331+ const vk::Extent2D &extent,
332+ const uint32_t image_count,
333+ const vk::SurfaceTransformFlagBitsKHR transform,
334+ const std::set<vk::ImageUsageFlagBits> &image_usage_flags,
335+ const vk::ImageCompressionFlagsEXT requested_compression,
336+ const vk::ImageCompressionFixedRateFlagsEXT requested_compression_fixed_rate) :
285337 device{device},
286- surface{surface}
338+ surface{surface},
339+ requested_compression{requested_compression},
340+ requested_compression_fixed_rate{requested_compression_fixed_rate}
287341{
288342 this ->present_mode_priority_list = present_mode_priority_list;
289343 this ->surface_format_priority_list = surface_format_priority_list;
@@ -305,13 +359,11 @@ HPPSwapchain::HPPSwapchain(vkb::core::DeviceCpp &device,
305359 // Choose best properties based on surface capabilities
306360 vk::SurfaceCapabilitiesKHR const surface_capabilities = device.get_gpu ().get_handle ().getSurfaceCapabilitiesKHR (surface);
307361
308- properties.old_swapchain = old_swapchain;
309- properties.image_count = clamp (image_count,
310- surface_capabilities.minImageCount ,
311- surface_capabilities.maxImageCount ? surface_capabilities.maxImageCount : std::numeric_limits<uint32_t >::max ());
362+ properties.old_swapchain = old_swapchain.get_handle ();
363+ properties.image_count = choose_image_count (image_count, surface_capabilities.minImageCount , surface_capabilities.maxImageCount );
312364 properties.extent = choose_extent (extent, surface_capabilities.minImageExtent , surface_capabilities.maxImageExtent , surface_capabilities.currentExtent );
313365 properties.surface_format = choose_surface_format (properties.surface_format , surface_formats, surface_format_priority_list);
314- properties.array_layers = 1 ;
366+ properties.array_layers = choose_image_array_layers ( 1U , surface_capabilities. maxImageArrayLayers ) ;
315367
316368 vk::FormatProperties const format_properties = device.get_gpu ().get_handle ().getFormatProperties (properties.surface_format .format );
317369 this ->image_usage_flags = choose_image_usage (image_usage_flags, surface_capabilities.supportedUsageFlags , format_properties.optimalTilingFeatures );
@@ -321,21 +373,75 @@ HPPSwapchain::HPPSwapchain(vkb::core::DeviceCpp &device,
321373 properties.composite_alpha = choose_composite_alpha (vk::CompositeAlphaFlagBitsKHR::eInherit, surface_capabilities.supportedCompositeAlpha );
322374 properties.present_mode = choose_present_mode (present_mode, present_modes, present_mode_priority_list);
323375
324- vk::SwapchainCreateInfoKHR const create_info{.surface = surface,
325- .minImageCount = properties.image_count ,
326- .imageFormat = properties.surface_format .format ,
327- .imageColorSpace = properties.surface_format .colorSpace ,
328- .imageExtent = properties.extent ,
329- .imageArrayLayers = properties.array_layers ,
330- .imageUsage = properties.image_usage ,
331- .preTransform = properties.pre_transform ,
332- .compositeAlpha = properties.composite_alpha ,
333- .presentMode = properties.present_mode ,
334- .oldSwapchain = properties.old_swapchain };
376+ vk::SwapchainCreateInfoKHR create_info{.surface = surface,
377+ .minImageCount = properties.image_count ,
378+ .imageFormat = properties.surface_format .format ,
379+ .imageColorSpace = properties.surface_format .colorSpace ,
380+ .imageExtent = properties.extent ,
381+ .imageArrayLayers = properties.array_layers ,
382+ .imageUsage = properties.image_usage ,
383+ .preTransform = properties.pre_transform ,
384+ .compositeAlpha = properties.composite_alpha ,
385+ .presentMode = properties.present_mode ,
386+ .oldSwapchain = properties.old_swapchain };
387+
388+ auto fixed_rate_flags = requested_compression_fixed_rate;
389+ vk::ImageCompressionControlEXT compression_control;
390+ compression_control.flags = requested_compression;
391+ if (device.is_extension_enabled (VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME))
392+ {
393+ create_info.pNext = &compression_control;
394+
395+ if (vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit == requested_compression)
396+ {
397+ // Do not support compression for multi-planar formats
398+ compression_control.compressionControlPlaneCount = 1 ;
399+ compression_control.pFixedRateFlags = &fixed_rate_flags;
400+ }
401+ else if (vk::ImageCompressionFlagBitsEXT::eDisabled == requested_compression)
402+ {
403+ LOGW (" (Swapchain) Disabling default (lossless) compression, which can negatively impact performance" )
404+ }
405+ }
406+ else
407+ {
408+ if (vk::ImageCompressionFlagBitsEXT::eDefault != requested_compression)
409+ {
410+ LOGW (" (Swapchain) Compression cannot be controlled because VK_EXT_image_compression_control_swapchain is not enabled" )
411+
412+ this ->requested_compression = vk::ImageCompressionFlagBitsEXT::eDefault;
413+ this ->requested_compression_fixed_rate = vk::ImageCompressionFixedRateFlagBitsEXT::eNone;
414+ }
415+ }
335416
336417 handle = device.get_handle ().createSwapchainKHR (create_info);
337418
338419 images = device.get_handle ().getSwapchainImagesKHR (handle);
420+
421+ if (device.is_extension_enabled (VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME) &&
422+ vk::ImageCompressionFlagBitsEXT::eFixedRateDefault == requested_compression)
423+ {
424+ // Check if fixed-rate compression was applied
425+ const auto applied_compression_fixed_rate = vkb::common::query_applied_compression (device.get_handle (), images[0 ]).imageCompressionFixedRateFlags ;
426+
427+ if (applied_compression_fixed_rate != requested_compression_fixed_rate)
428+ {
429+ LOGW (" (Swapchain) Requested fixed-rate compression ({}) was not applied, instead images use {}" ,
430+ vk::to_string (requested_compression_fixed_rate),
431+ vk::to_string (applied_compression_fixed_rate));
432+
433+ this ->requested_compression_fixed_rate = applied_compression_fixed_rate;
434+
435+ if (vk::ImageCompressionFixedRateFlagBitsEXT::eNone == applied_compression_fixed_rate)
436+ {
437+ this ->requested_compression = vk::ImageCompressionFlagBitsEXT::eDefault;
438+ }
439+ }
440+ else
441+ {
442+ LOGI (" (Swapchain) Applied fixed-rate compression: {}" , vk::to_string (applied_compression_fixed_rate));
443+ }
444+ }
339445}
340446
341447HPPSwapchain::~HPPSwapchain ()
0 commit comments