1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use crate::graphics::vulkan::WindowSurface;
use anyhow::Result;
use ash::vk;
pub fn choose_image_count(
window_surface: &dyn WindowSurface,
physical_device: &vk::PhysicalDevice,
) -> Result<u32> {
let capabilities =
unsafe { window_surface.surface_capabilities(physical_device)? };
let proposed_image_count = capabilities.min_image_count + 1;
if capabilities.max_image_count > 0 {
Ok(std::cmp::min(
proposed_image_count,
capabilities.max_image_count,
))
} else {
Ok(proposed_image_count)
}
}
pub fn choose_surface_format(
window_surface: &dyn WindowSurface,
physical_device: &vk::PhysicalDevice,
) -> vk::SurfaceFormatKHR {
let formats = unsafe { window_surface.supported_formats(physical_device) };
log::info!("available formats {:?}", formats);
let format = formats
.iter()
.cloned()
.find(|format| {
format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
&& format.format == vk::Format::B8G8R8A8_SRGB
})
.unwrap_or_else(|| formats[0]);
log::info!("chosen format {:?}", format);
format
}
pub fn choose_present_mode(
window_surface: &dyn WindowSurface,
physical_device: &vk::PhysicalDevice,
) -> vk::PresentModeKHR {
let modes =
unsafe { window_surface.supported_presentation_modes(physical_device) };
log::info!("available presentation modes {:?}", modes);
let mode = if modes.contains(&vk::PresentModeKHR::MAILBOX) {
vk::PresentModeKHR::MAILBOX
} else {
vk::PresentModeKHR::IMMEDIATE
};
log::info!("chosen presentation mode {:?}", mode);
mode
}
pub fn choose_swap_extent(
window_surface: &dyn WindowSurface,
physical_device: &vk::PhysicalDevice,
) -> Result<vk::Extent2D> {
let capabilities =
unsafe { window_surface.surface_capabilities(physical_device)? };
if capabilities.current_extent.width != u32::MAX {
log::debug!("use current extent {:?}", capabilities.current_extent);
Ok(capabilities.current_extent)
} else {
let (width, height) = window_surface.framebuffer_size();
let extent = vk::Extent2D {
width: clamp(
width,
capabilities.min_image_extent.width,
capabilities.max_image_extent.width,
),
height: clamp(
height,
capabilities.min_image_extent.height,
capabilities.max_image_extent.height,
),
};
log::debug!("use computed extent {:?}", extent);
Ok(extent)
}
}
fn clamp(x: u32, min: u32, max: u32) -> u32 {
std::cmp::max(min, std::cmp::min(x, max))
}