bedrock/surface/
swapchain.rs1use crate::{ffi_helper::slice_as_ptr_empty_null, *};
2use bedrock_vk::{self as brvk, TypedVulkanStructure};
3use derives::implements;
4
5pub trait Swapchain: VkHandle<Handle = brvk::VkSwapchainKHR> + DeviceChild {
6 #[implements]
13 #[inline]
14 fn image_count(&self) -> crate::Result<u32> {
15 unsafe {
16 crate::vkfn_wrapper::get_swapchain_image_count(self.device_transparent_ref(), self.as_transparent_ref())
17 }
18 }
19
20 #[implements]
27 #[inline(always)]
28 fn images(&self, sink: &mut [core::mem::MaybeUninit<brvk::VkImage>]) -> crate::Result<ArrayQueryResult<u32>> {
29 unsafe {
30 crate::vkfn_wrapper::get_swapchain_images(self.device_transparent_ref(), self.as_transparent_ref(), sink)
31 }
32 }
33
34 #[implements("VK_EXT_full_screen_exclusive")]
43 #[inline(always)]
44 fn acquire_full_screen_exclusive_mode(&self) -> crate::Result<()>
45 where
46 Self::ConcreteDevice: DeviceFullScreenExclusiveExtension,
47 {
48 unsafe {
49 self.device()
50 .acquire_full_screen_exclusive_mode(self.device_transparent_ref(), self.as_transparent_ref())
51 }
52 }
53
54 #[implements("VK_EXT_full_screen_exclusive")]
56 #[inline(always)]
57 fn release_full_screen_exclusive_mode(&self) -> crate::Result<()>
58 where
59 Self::ConcreteDevice: DeviceFullScreenExclusiveExtension,
60 {
61 unsafe {
62 self.device()
63 .release_full_screen_exclusive_mode(self.device_transparent_ref(), self.as_transparent_ref())
64 }
65 }
66}
67DerefContainerBracketImpl!(for Swapchain {});
68
69pub trait SwapchainMut: Swapchain + VkHandleMut {
70 #[implements]
80 fn acquire_next(&mut self, timeout: Option<u64>, completion: CompletionHandlerMut) -> crate::Result<u32> {
81 let (semaphore, fence) = match completion {
82 CompletionHandlerMut::Host(f) => (None, Some(f)),
83 CompletionHandlerMut::Queue(s) => (Some(s), None),
84 };
85
86 unsafe {
87 crate::vkfn_wrapper::acquire_next_image(
88 self.device_transparent_ref(),
89 VkHandleRefMut::dangling(self.native_ptr()),
90 timeout.unwrap_or(u64::MAX),
91 semaphore,
92 fence,
93 )
94 }
95 }
96}
97DerefContainerBracketImpl!(for mut SwapchainMut {});
98
99pub trait SwapchainImageExt: Swapchain {
100 fn format(&self) -> brvk::VkFormat;
101 fn extent(&self) -> brvk::VkExtent2D;
102
103 #[implements("alloc")]
110 fn images_alloc(&self) -> crate::Result<Vec<crate::SwapchainImage<&Self>>> {
111 let n = self.image_count()? as usize;
112 if n == 0 {
113 return Ok(crate::alloc::empty_sink_buffer());
115 }
116
117 let mut xs = crate::alloc::reserve(n);
118 let res = self.images(xs.spare_capacity_mut())?.assert_complete();
119 unsafe {
120 xs.set_len(res as _);
121 }
122
123 Ok(crate::alloc::collect_vec(xs.into_iter().map(move |r| {
124 let ext = self.extent();
125 crate::SwapchainImage(
126 r,
127 self,
128 self.format(),
129 brvk::VkExtent3D {
130 width: ext.width,
131 height: ext.height,
132 depth: 1,
133 },
134 )
135 })))
136 }
137}
138DerefContainerBracketImpl!(for SwapchainImageExt {
139 #[inline(always)]
140 fn format(&self) -> brvk::VkFormat {
141 T::format(self)
142 }
143
144 #[inline(always)]
145 fn extent(&self) -> brvk::VkExtent2D {
146 T::extent(self)
147 }
148});
149
150#[repr(transparent)]
151#[derive(Clone)]
152pub struct SwapchainCreateInfo<'r, 'n, 'sw>(
153 brvk::VkSwapchainCreateInfoKHR,
154 #[allow(clippy::type_complexity)]
155 core::marker::PhantomData<(
156 &'r dyn VkHandle<Handle = brvk::VkSurfaceKHR>,
157 Option<&'n dyn brvk::VulkanStructure>,
158 Option<&'r [u32]>,
159 Option<&'sw dyn VkHandle<Handle = brvk::VkSwapchainKHR>>,
160 )>,
161);
162impl<'r, 'n, 'sw> SwapchainCreateInfo<'r, 'n, 'sw> {
163 #[inline]
164 pub fn new(
165 surface: &'r (impl VkHandle<Handle = brvk::VkSurfaceKHR> + ?Sized),
166 min_image_count: u32,
167 format: brvk::VkSurfaceFormatKHR,
168 extent: brvk::VkExtent2D,
169 usage: ImageUsageFlags,
170 ) -> Self {
171 Self(
172 brvk::VkSwapchainCreateInfoKHR {
173 sType: brvk::VkSwapchainCreateInfoKHR::TYPE,
174 pNext: core::ptr::null(),
175 flags: 0,
176 surface: surface.native_ptr(),
177 minImageCount: min_image_count,
178 imageFormat: format.format,
179 imageColorSpace: format.colorSpace,
180 imageExtent: extent,
181 imageArrayLayers: 1,
182 imageUsage: usage.bits(),
183 imageSharingMode: brvk::VK_SHARING_MODE_EXCLUSIVE,
184 queueFamilyIndexCount: 0,
185 pQueueFamilyIndices: core::ptr::null(),
186 preTransform: brvk::VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR,
187 compositeAlpha: brvk::VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
188 presentMode: brvk::VK_PRESENT_MODE_IMMEDIATE_KHR,
189 clipped: false as _,
190 oldSwapchain: None,
191 },
192 core::marker::PhantomData,
193 )
194 }
195
196 pub const unsafe fn from_raw(raw: brvk::VkSwapchainCreateInfoKHR) -> Self {
200 Self(raw, core::marker::PhantomData)
201 }
202
203 pub const fn into_raw(self) -> brvk::VkSwapchainCreateInfoKHR {
204 self.0
205 }
206
207 pub const fn with_next(mut self, next: &'n (impl brvk::VulkanStructure + ?Sized)) -> Self {
208 self.0.pNext = next as *const _ as _;
209 self
210 }
211
212 pub const fn array_layers(mut self, layers: u32) -> Self {
213 self.0.imageArrayLayers = layers;
214 self
215 }
216
217 pub const fn shared(mut self, queue_families: &'r [u32]) -> Self {
218 assert!(!queue_families.is_empty(), "empty families not allowed");
219
220 self.0.imageSharingMode = brvk::VK_SHARING_MODE_CONCURRENT;
221 self.0.queueFamilyIndexCount = queue_families.len() as _;
222 self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(queue_families);
223 self
224 }
225
226 pub const fn exclusive(mut self) -> Self {
227 self.0.imageSharingMode = brvk::VK_SHARING_MODE_EXCLUSIVE;
228 self.0.queueFamilyIndexCount = 0;
229 self.0.pQueueFamilyIndices = core::ptr::null();
230
231 self
232 }
233
234 pub const fn pre_transform(mut self, tf: SurfaceTransformFlags) -> Self {
236 self.0.preTransform = tf.bits();
237 self
238 }
239
240 pub const fn composite_alpha(mut self, a: CompositeAlphaFlags) -> Self {
242 self.0.compositeAlpha = a.bits();
243 self
244 }
245
246 pub const fn present_mode(mut self, mode: PresentMode) -> Self {
248 self.0.presentMode = mode as _;
249 self
250 }
251
252 pub const fn enable_clip(mut self) -> Self {
255 self.0.clipped = true as _;
256 self
257 }
258
259 #[inline(always)]
260 pub fn old_swapchain(
261 mut self,
262 old_swapchain: &'sw (impl VkHandle<Handle = brvk::VkSwapchainKHR> + ?Sized),
263 ) -> Self {
264 self.0.oldSwapchain = Some(old_swapchain.native_ptr());
265 self
266 }
267}