bedrock/surface/
swapchain.rs1use crate::{ffi_helper::slice_as_ptr_empty_null, *};
2use derives::implements;
3
4use super::CompletionHandlerMut;
5
6pub trait Swapchain: VkHandle<Handle = VkSwapchainKHR> + DeviceChild {
7 fn format(&self) -> VkFormat;
8 fn size(&self) -> &VkExtent2D;
9
10 #[implements]
20 fn acquire_next(&mut self, timeout: Option<u64>, completion: CompletionHandlerMut) -> crate::Result<u32> {
21 let (semaphore, fence) = match completion {
22 CompletionHandlerMut::Host(f) => (VkSemaphore::NULL, f.0),
23 CompletionHandlerMut::Queue(s) => (s.0, VkFence::NULL),
24 };
25
26 let mut n = 0;
27 unsafe {
28 crate::vkfn::acquire_next_image_khr(
29 self.device().native_ptr(),
30 self.native_ptr(),
31 timeout.unwrap_or(std::u64::MAX),
32 semaphore,
33 fence,
34 &mut n,
35 )
36 .into_result()
37 .map(|_| n)
38 }
39 }
40
41 #[implements("VK_EXT_full_screen_exclusive")]
50 fn acquire_full_screen_exclusive_mode(&self) -> crate::Result<()>
51 where
52 Self::ConcreteDevice: DeviceFullScreenExclusiveExtension,
53 {
54 unsafe {
55 self.device().acquire_full_screen_exclusive_mode_ext_fn().0(self.device().native_ptr(), self.native_ptr())
56 .into_result()
57 .map(drop)
58 }
59 }
60
61 #[implements("VK_EXT_full_screen_exclusive")]
63 fn release_full_screen_exclusive_mode(&self) -> crate::Result<()>
64 where
65 Self::ConcreteDevice: DeviceFullScreenExclusiveExtension,
66 {
67 unsafe {
68 self.device().release_full_screen_exclusive_mode_ext_fn().0(self.device().native_ptr(), self.native_ptr())
69 .into_result()
70 .map(drop)
71 }
72 }
73
74 #[implements]
81 #[inline]
82 fn image_count(&self) -> crate::Result<u32> {
83 let mut n = 0;
84 unsafe {
85 crate::vkfn::get_swapchain_images_khr(
86 self.device_handle(),
87 self.native_ptr(),
88 &mut n,
89 core::ptr::null_mut(),
90 )
91 .into_result()?;
92 }
93
94 Ok(n)
95 }
96
97 #[implements]
104 #[inline]
105 fn images(&self, sink: &mut [core::mem::MaybeUninit<VkImage>]) -> crate::Result<(u32, crate::ArrayQueryResult)> {
106 let mut n = sink.len() as _;
107 let r = unsafe {
108 crate::vkfn::get_swapchain_images_khr(
109 self.device_handle(),
110 self.native_ptr(),
111 &mut n,
112 sink.as_mut_ptr() as _,
113 )
114 };
115
116 match r {
117 VK_SUCCESS => Ok((n, crate::ArrayQueryResult::Complete)),
118 VK_INCOMPLETE => Ok((n, crate::ArrayQueryResult::Incomplete)),
119 e => Err(e),
120 }
121 }
122
123 #[implements("alloc")]
130 fn images_alloc(&self) -> crate::Result<Vec<crate::SwapchainImage<&Self>>>
131 where
132 Self: Sized,
133 {
134 let n = self.image_count()? as usize;
135 if n == 0 {
136 return Ok(crate::alloc::empty_sink_buffer());
138 }
139
140 let mut xs = Vec::with_capacity(n);
141 let (n, _) = self.images(xs.spare_capacity_mut())?;
142 unsafe {
143 xs.set_len(n as _);
144 }
145
146 Ok(crate::alloc::collect_vec(xs.into_iter().map(move |r| {
147 crate::SwapchainImage(r, self, self.size().with_depth(1))
148 })))
149 }
150}
151DerefContainerBracketImpl!(for Swapchain {
152 #[inline(always)]
153 fn format(&self) -> VkFormat {
154 T::format(self)
155 }
156
157 #[inline(always)]
158 fn size(&self) -> &VkExtent2D {
159 T::size(self)
160 }
161});
162
163#[repr(transparent)]
164#[derive(Clone)]
165pub struct SwapchainCreateInfo<'r, 'n, 'sw>(
166 VkSwapchainCreateInfoKHR,
167 core::marker::PhantomData<(
168 &'r dyn VkHandle<Handle = VkSurfaceKHR>,
169 Option<&'n dyn VulkanStructure>,
170 Option<&'r [u32]>,
171 Option<&'sw dyn VkHandle<Handle = VkSwapchainKHR>>,
172 )>,
173);
174impl<'r, 'n, 'sw> SwapchainCreateInfo<'r, 'n, 'sw> {
175 #[inline]
176 pub fn new(
177 surface: &'r (impl VkHandle<Handle = VkSurfaceKHR> + ?Sized),
178 min_image_count: u32,
179 format: VkSurfaceFormatKHR,
180 extent: VkExtent2D,
181 usage: ImageUsageFlags,
182 ) -> Self {
183 Self(
184 VkSwapchainCreateInfoKHR {
185 sType: VkSwapchainCreateInfoKHR::TYPE,
186 pNext: core::ptr::null(),
187 flags: 0,
188 surface: surface.native_ptr(),
189 minImageCount: min_image_count,
190 imageFormat: format.format,
191 imageColorSpace: format.colorSpace,
192 imageExtent: extent,
193 imageArrayLayers: 1,
194 imageUsage: usage.bits(),
195 imageSharingMode: VK_SHARING_MODE_EXCLUSIVE,
196 queueFamilyIndexCount: 0,
197 pQueueFamilyIndices: core::ptr::null(),
198 preTransform: VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR,
199 compositeAlpha: VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
200 presentMode: VK_PRESENT_MODE_IMMEDIATE_KHR,
201 clipped: false as _,
202 oldSwapchain: VkSwapchainKHR::NULL,
203 },
204 core::marker::PhantomData,
205 )
206 }
207
208 pub const unsafe fn from_raw(raw: VkSwapchainCreateInfoKHR) -> Self {
209 Self(raw, core::marker::PhantomData)
210 }
211
212 pub const fn into_raw(self) -> VkSwapchainCreateInfoKHR {
213 self.0
214 }
215
216 pub const fn with_next(mut self, next: &'n (impl VulkanStructure + ?Sized)) -> Self {
217 self.0.pNext = next as *const _ as _;
218 self
219 }
220
221 pub const fn array_layers(mut self, layers: u32) -> Self {
222 self.0.imageArrayLayers = layers;
223 self
224 }
225
226 pub const fn shared(mut self, queue_families: &'r [u32]) -> Self {
227 assert!(queue_families.len() > 0, "empty families not allowed");
228
229 self.0.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
230 self.0.queueFamilyIndexCount = queue_families.len() as _;
231 self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(queue_families);
232 self
233 }
234
235 pub const fn exclusive(mut self) -> Self {
236 self.0.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
237 self.0.queueFamilyIndexCount = 0;
238 self.0.pQueueFamilyIndices = core::ptr::null();
239
240 self
241 }
242
243 pub const fn pre_transform(mut self, tf: SurfaceTransformFlags) -> Self {
245 self.0.preTransform = tf.bits();
246 self
247 }
248
249 pub const fn composite_alpha(mut self, a: CompositeAlphaFlags) -> Self {
251 self.0.compositeAlpha = a.bits();
252 self
253 }
254
255 pub const fn present_mode(mut self, mode: PresentMode) -> Self {
257 self.0.presentMode = mode as _;
258 self
259 }
260
261 pub const fn enable_clip(mut self) -> Self {
264 self.0.clipped = true as _;
265 self
266 }
267
268 #[inline(always)]
269 pub fn old_swapchain(mut self, old_swapchain: &'sw (impl VkHandle<Handle = VkSwapchainKHR> + ?Sized)) -> Self {
270 self.0.oldSwapchain = old_swapchain.native_ptr();
271 self
272 }
273}