// ================================================================================
//  Presentation and Swapchain Helper Methods
// ================================================================================
/// Based on the capabilities of the surface, the physical device, and the
/// configuration of sarekt, creates a swapchain with the appropriate
/// configuration (format, color space, present mode, and extent).
Presentation and Swapchain Helper Methods
Based on the capabilities of the surface, the physical device, and the
configuration of sarekt, creates a swapchain with the appropriate
configuration (format, color space, present mode, and extent).
Presentation and Swapchain Helper Methods Based on the capabilities of the surface the physical device and the configuration of sarekt creates a swapchain with the appropriate configuration ( format color space present mode and extent ) .
fn create_swapchain(
    surface_and_extension: &SurfaceAndExtension,
    swapchain_extension: &ash::extensions::khr::Swapchain, physical_device: vk::PhysicalDevice,
    queue_family_indices: &QueueFamilyIndices, requested_width: u32, requested_height: u32,
    requested_present_mode: PresentMode, old_swapchain: Option<vk::SwapchainKHR>,
  ) -> SarektResult<(vk::SwapchainKHR, vk::Format, vk::Extent2D)> {
    let swapchain_support =
      VulkanDeviceStructures::query_swap_chain_support(surface_and_extension, physical_device)?;
    let format = Self::choose_swap_surface_format(&swapchain_support.formats);
    let present_mode =
      Self::choose_presentation_mode(&swapchain_support.present_modes, requested_present_mode);
    let extent = Self::choose_swap_extent(
      &swapchain_support.capabilities,
      requested_width,
      requested_height,
    );
    // Select minimum number of images to render to.  For triple buffering this
    // would be 3, etc. But don't exceed the max.  Implementation may create more
    // than this depending on present mode.
    // [vulkan tutorial](https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Swap_chain)
    // recommends setting this to min + 1 because if we select minimum we may wait
    // on internal driver operations.
    let max_image_count = swapchain_support.capabilities.max_image_count;
    let max_image_count = if max_image_count == 0 {
      u32::max_value()
    } else {
      max_image_count
    };
    let min_image_count = (swapchain_support.capabilities.min_image_count + 1).min(max_image_count);
    let sharing_mode = if queue_family_indices.graphics_queue_family.unwrap()
      != queue_family_indices.presentation_queue_family.unwrap()
    {
      // Concurrent sharing mode because the images will need to be accessed by more
      // than one queue family.
      vk::SharingMode::CONCURRENT
    } else {
      // Exclusive (probly) has best performance, not sharing the image with other
      // queue families.
      vk::SharingMode::EXCLUSIVE
    };
    let swapchain_ci = vk::SwapchainCreateInfoKHR::builder()
      .surface(surface_and_extension.surface)
      .min_image_count(min_image_count)
      .image_format(format.format)
      .image_color_space(format.color_space)
      .image_extent(extent)
      .image_array_layers(1) // Number of views (multiview/stereo surface for 3D applications with glasses or maybe VR).
      .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) // We'll just be rendering colors to this.  We could render to another image and transfer here after post processing but we're not.
      .image_sharing_mode(sharing_mode)
      .queue_family_indices(&queue_family_indices.as_vec().unwrap())
      .pre_transform(swapchain_support.capabilities.current_transform) // Match the transform of the swapchain, I'm not trying to redner upside down!
      .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) // No alpha blending within the window system for now.
      .present_mode(present_mode)
      .clipped(true) // Go ahead and discard rendering ops we dont need (window half off screen).
      .old_swapchain(old_swapchain.unwrap_or_else(vk::SwapchainKHR::null)) // Pass old swapchain for recreation.
      .build();
    let swapchain = unsafe { swapchain_extension.create_swapchain(&swapchain_ci, None)? };
    Ok((swapchain, format.format, extent))
  }
fn create_swapchain ( surface_and_extension : & SurfaceAndExtension , swapchain_extension : & ash :: extensions :: khr :: Swapchain , physical_device : vk :: PhysicalDevice , queue_family_indices : & QueueFamilyIndices , requested_width : u32 , requested_height : u32 , requested_present_mode : PresentMode , old_swapchain : Option < vk :: SwapchainKHR > , ) -> SarektResult < ( vk :: SwapchainKHR , vk :: Format , vk :: Extent2D ) > { let swapchain_support = VulkanDeviceStructures :: query_swap_chain_support ( surface_and_extension , physical_device ) ? ; let format = Self :: choose_swap_surface_format ( & swapchain_support . formats ) ; let present_mode = Self :: choose_presentation_mode ( & swapchain_support . present_modes , requested_present_mode ) ; let extent = Self :: choose_swap_extent ( & swapchain_support . capabilities , requested_width , requested_height , ) ; // Select minimum number of images to render to.  For triple buffering this // would be 3, etc. But don't exceed the max.  Implementation may create more // than this depending on present mode. // [vulkan tutorial](https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Swap_chain) // recommends setting this to min + 1 because if we select minimum we may wait // on internal driver operations. let max_image_count = swapchain_support . capabilities . max_image_count ; let max_image_count = if max_image_count == 0 { u32 :: max_value ( ) } else { max_image_count } ; let min_image_count = ( swapchain_support . capabilities . min_image_count + 1 ) . min ( max_image_count ) ; let sharing_mode = if queue_family_indices . graphics_queue_family . unwrap ( ) != queue_family_indices . presentation_queue_family . unwrap ( ) { // Concurrent sharing mode because the images will need to be accessed by more // than one queue family. vk :: SharingMode :: CONCURRENT } else { // Exclusive (probly) has best performance, not sharing the image with other // queue families. vk :: SharingMode :: EXCLUSIVE } ; let swapchain_ci = vk :: SwapchainCreateInfoKHR :: builder ( ) . surface ( surface_and_extension . surface ) . min_image_count ( min_image_count ) . image_format ( format . format ) . image_color_space ( format . color_space ) . image_extent ( extent ) . image_array_layers ( 1 ) // Number of views (multiview/stereo surface for 3D applications with glasses or maybe VR). . image_usage ( vk :: ImageUsageFlags :: COLOR_ATTACHMENT ) // We'll just be rendering colors to this.  We could render to another image and transfer here after post processing but we're not. . image_sharing_mode ( sharing_mode ) . queue_family_indices ( & queue_family_indices . as_vec ( ) . unwrap ( ) ) . pre_transform ( swapchain_support . capabilities . current_transform ) // Match the transform of the swapchain, I'm not trying to redner upside down! . composite_alpha ( vk :: CompositeAlphaFlagsKHR :: OPAQUE ) // No alpha blending within the window system for now. . present_mode ( present_mode ) . clipped ( true ) // Go ahead and discard rendering ops we dont need (window half off screen). . old_swapchain ( old_swapchain . unwrap_or_else ( vk :: SwapchainKHR :: null ) ) // Pass old swapchain for recreation. . build ( ) ; let swapchain = unsafe { swapchain_extension . create_swapchain ( & swapchain_ci , None ) ? } ; Ok ( ( swapchain , format . format , extent ) ) }
Presentation and Swapchain Helper Methods
Based on the capabilities of the surface, the physical device, and the
configuration of sarekt, creates a swapchain with the appropriate
configuration (format, color space, present mode, and extent).
Presentation and Swapchain Helper Methods Based on the capabilities of the surface the physical device and the configuration of sarekt creates a swapchain with the appropriate configuration ( format color space present mode and extent ) .
surface_and_extension
&SurfaceAndExtension
swapchain_extension
&ash::extensions::khr::Swapchain
physical_device
vk::PhysicalDevice
queue_family_indices
&QueueFamilyIndices
requested_width
u32
requested_height
u32
requested_present_mode
PresentMode
old_swapchain
Option<vk::SwapchainKHR>