1use crate::ffi_helper::slice_as_ptr_empty_null;
2use crate::*;
3use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle, VulkanStructure};
4use derives::implements;
5
6use super::DeviceChildHandle;
7
8#[derive(VkHandle, VkObject)]
10#[VkObject(type = brvk::VkSwapchainKHR::OBJECT_TYPE)]
11pub struct SurfaceSwapchainObject<
12 Device: VkHandle<Handle = brvk::VkDevice>,
13 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
14> {
15 #[handle]
16 pub(crate) handle: brvk::VkSwapchainKHR,
17 pub(crate) device: Device,
18 pub(crate) surface: Surface,
19 pub(crate) format: brvk::VkFormat,
20 pub(crate) extent: brvk::VkExtent2D,
21}
22#[implements]
23impl<Device, Surface> Drop for SurfaceSwapchainObject<Device, Surface>
24where
25 Device: VkHandle<Handle = brvk::VkDevice>,
26 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
27{
28 #[inline(always)]
29 fn drop(&mut self) {
30 unsafe {
31 crate::vkfn_wrapper::destroy_swapchain(
32 self.device_transparent_ref(),
33 VkHandleRefMut::dangling(self.handle),
34 None,
35 );
36 }
37 }
38}
39unsafe impl<Device, Surface> Sync for SurfaceSwapchainObject<Device, Surface>
40where
41 Device: VkHandle<Handle = brvk::VkDevice> + Sync,
42 Surface: VkHandle<Handle = brvk::VkSurfaceKHR> + Sync,
43{
44}
45unsafe impl<Device, Surface> Send for SurfaceSwapchainObject<Device, Surface>
46where
47 Device: VkHandle<Handle = brvk::VkDevice> + Send,
48 Surface: VkHandle<Handle = brvk::VkSurfaceKHR> + Send,
49{
50}
51impl<Device, Surface> DeviceChildHandle for SurfaceSwapchainObject<Device, Surface>
52where
53 Device: VkHandle<Handle = brvk::VkDevice>,
54 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
55{
56 #[inline(always)]
57 fn device_handle(&self) -> brvk::VkDevice {
58 self.device.native_ptr()
59 }
60}
61impl<Device, Surface> DeviceChild for SurfaceSwapchainObject<Device, Surface>
62where
63 Device: crate::Device,
64 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
65{
66 type ConcreteDevice = Device;
67
68 #[inline(always)]
69 fn device(&self) -> &Self::ConcreteDevice {
70 &self.device
71 }
72}
73impl<Device, Surface> Swapchain for SurfaceSwapchainObject<Device, Surface>
74where
75 Device: crate::Device,
76 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
77{
78}
79impl<Device, Surface> SwapchainMut for SurfaceSwapchainObject<Device, Surface>
80where
81 Device: crate::Device,
82 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
83{
84}
85impl<Device, Surface> SwapchainImageExt for SurfaceSwapchainObject<Device, Surface>
86where
87 Device: crate::Device,
88 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
89{
90 #[inline(always)]
91 fn format(&self) -> brvk::VkFormat {
92 self.format
93 }
94
95 #[inline(always)]
96 fn extent(&self) -> brvk::VkExtent2D {
97 self.extent
98 }
99}
100impl<Device, Surface> SurfaceSwapchainObject<Device, Surface>
101where
102 Device: VkHandle<Handle = brvk::VkDevice>,
103 Surface: VkHandle<Handle = brvk::VkSurfaceKHR>,
104{
105 pub const fn unmanage(self) -> (Device, Surface, brvk::VkSwapchainKHR) {
107 let device = unsafe { core::ptr::read(&self.device) };
108 let surface = unsafe { core::ptr::read(&self.surface) };
109 let swapchain = self.handle;
110 core::mem::forget(self);
111
112 (device, surface, swapchain)
113 }
114
115 #[implements]
117 pub fn deconstruct(mut self) -> (Device, Surface) {
118 let d = unsafe { core::ptr::read(&self.device) };
119 let s = unsafe { core::ptr::read(&self.surface) };
120
121 unsafe {
123 crate::vkfn_wrapper::destroy_swapchain(d.as_transparent_ref(), self.as_transparent_ref_mut(), None);
124 }
125 core::mem::forget(self);
126
127 (d, s)
128 }
129}
130impl<Surface: crate::Surface> super::TransferSurfaceObject for SwapchainWithSurfaceBuilder<'_, '_, Surface> {
131 type ConcreteSurface = Surface;
132
133 #[inline(always)]
134 fn transfer_surface(self) -> Self::ConcreteSurface {
135 self.1
136 }
137}
138
139pub struct SwapchainWithSurfaceBuilder<'n, 'sw, Surface: crate::Surface>(
141 brvk::VkSwapchainCreateInfoKHR,
142 Surface,
143 #[allow(clippy::type_complexity)]
144 core::marker::PhantomData<(
145 Option<&'n dyn brvk::VulkanStructure>,
146 Option<&'sw dyn VkHandle<Handle = brvk::VkSwapchainKHR>>,
147 )>,
148);
149impl<'n, 'sw, Surface: crate::Surface> SwapchainWithSurfaceBuilder<'n, 'sw, Surface> {
150 pub fn new(
151 surface: Surface,
152 min_image_count: u32,
153 format: brvk::VkSurfaceFormatKHR,
154 extent: brvk::VkExtent2D,
155 usage: ImageUsageFlags,
156 ) -> Self {
157 Self(
158 brvk::VkSwapchainCreateInfoKHR {
159 sType: brvk::VkSwapchainCreateInfoKHR::TYPE,
160 pNext: core::ptr::null(),
161 flags: 0,
162 surface: surface.native_ptr(),
163 minImageCount: min_image_count,
164 imageFormat: format.format,
165 imageColorSpace: format.colorSpace,
166 imageExtent: extent,
167 imageArrayLayers: 1,
168 imageUsage: usage.bits(),
169 imageSharingMode: brvk::VK_SHARING_MODE_EXCLUSIVE,
170 preTransform: brvk::VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR,
171 compositeAlpha: brvk::VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
172 presentMode: PresentMode::FIFO as _,
173 queueFamilyIndexCount: 0,
174 pQueueFamilyIndices: core::ptr::null(),
175 clipped: false as _,
176 oldSwapchain: None,
177 },
178 surface,
179 core::marker::PhantomData,
180 )
181 }
182
183 pub const fn with_next(mut self, next: &'n (impl brvk::VulkanStructure + ?Sized)) -> Self {
184 self.0.pNext = next as *const _ as _;
185 self
186 }
187
188 pub const fn array_layers(mut self, layers: u32) -> Self {
189 self.0.imageArrayLayers = layers;
190 self
191 }
192
193 pub const fn shared(mut self, queue_families: &[u32]) -> Self {
194 assert!(!queue_families.is_empty(), "empty families not allowed");
195
196 self.0.imageSharingMode = brvk::VK_SHARING_MODE_CONCURRENT;
197 self.0.queueFamilyIndexCount = queue_families.len() as _;
198 self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(queue_families);
199 self
200 }
201
202 pub const fn exclusive(mut self) -> Self {
203 self.0.imageSharingMode = brvk::VK_SHARING_MODE_EXCLUSIVE;
204 self.0.queueFamilyIndexCount = 0;
205 self.0.pQueueFamilyIndices = core::ptr::null();
206
207 self
208 }
209
210 pub const fn pre_transform(mut self, tf: SurfaceTransformFlags) -> Self {
212 self.0.preTransform = tf.bits();
213 self
214 }
215
216 pub const fn composite_alpha(mut self, a: CompositeAlphaFlags) -> Self {
218 self.0.compositeAlpha = a.bits();
219 self
220 }
221
222 pub const fn present_mode(mut self, mode: PresentMode) -> Self {
224 self.0.presentMode = mode as _;
225 self
226 }
227
228 pub const fn enable_clip(mut self) -> Self {
231 self.0.clipped = true as _;
232 self
233 }
234
235 #[inline(always)]
236 pub fn old_swapchain(mut self, sw: &'sw (impl VkHandle<Handle = brvk::VkSwapchainKHR> + ?Sized)) -> Self {
237 self.0.oldSwapchain = Some(sw.native_ptr());
238 self
239 }
240
241 #[implements]
251 pub fn create<Device: crate::Device>(
252 mut self,
253 device: Device,
254 ) -> crate::Result<SurfaceSwapchainObject<Device, Surface>> {
255 let mut structure = core::mem::MaybeUninit::uninit();
256 self.build(unsafe { &mut *structure.as_mut_ptr() });
257 let structure = unsafe { structure.assume_init() };
258
259 let handle = {
260 crate::vkfn_wrapper::create_swapchain(
261 device.as_transparent_ref(),
262 unsafe { core::mem::transmute::<&brvk::VkSwapchainCreateInfoKHR, &SwapchainCreateInfo>(&structure) },
263 None,
264 )?
265 };
266
267 Ok(SurfaceSwapchainObject {
268 handle,
269 device,
270 surface: self.1,
271 format: structure.imageFormat,
272 extent: structure.imageExtent,
273 })
274 }
275}
276impl<Surface: crate::Surface> VulkanStructureProvider for SwapchainWithSurfaceBuilder<'_, '_, Surface> {
277 type RootStructure = brvk::VkSwapchainCreateInfoKHR;
278
279 #[inline(always)]
280 fn build<'r, 's: 'r>(
281 &'s mut self,
282 root: &'s mut brvk::VkSwapchainCreateInfoKHR,
283 ) -> &'r mut brvk::GenericVulkanStructure {
284 *root = self.0.clone();
285 root.as_generic_mut()
286 }
287}