1use crate::ffi_helper::slice_as_ptr_empty_null;
2use crate::*;
3use derives::implements;
4
5use super::DeviceChildHandle;
6
7#[derive(VkHandle, VkObject)]
9#[VkObject(type = VkSwapchainKHR::OBJECT_TYPE)]
10pub struct SurfaceSwapchainObject<Device: VkHandle<Handle = VkDevice>, Surface: VkHandle<Handle = VkSurfaceKHR>> {
11 #[handle]
12 pub(crate) handle: VkSwapchainKHR,
13 pub(crate) device: Device,
14 pub(crate) surface: Surface,
15 pub(crate) format: VkFormat,
16 pub(crate) extent: VkExtent2D,
17}
18#[implements]
19impl<Device, Surface> Drop for SurfaceSwapchainObject<Device, Surface>
20where
21 Device: VkHandle<Handle = VkDevice>,
22 Surface: VkHandle<Handle = VkSurfaceKHR>,
23{
24 #[inline(always)]
25 fn drop(&mut self) {
26 unsafe {
27 crate::vkfn::destroy_swapchain_khr(self.device.native_ptr(), self.handle, core::ptr::null());
28 }
29 }
30}
31unsafe impl<Device, Surface> Sync for SurfaceSwapchainObject<Device, Surface>
32where
33 Device: VkHandle<Handle = VkDevice> + Sync,
34 Surface: VkHandle<Handle = VkSurfaceKHR> + Sync,
35{
36}
37unsafe impl<Device, Surface> Send for SurfaceSwapchainObject<Device, Surface>
38where
39 Device: VkHandle<Handle = VkDevice> + Send,
40 Surface: VkHandle<Handle = VkSurfaceKHR> + Send,
41{
42}
43impl<Device, Surface> DeviceChildHandle for SurfaceSwapchainObject<Device, Surface>
44where
45 Device: VkHandle<Handle = VkDevice>,
46 Surface: VkHandle<Handle = VkSurfaceKHR>,
47{
48 #[inline(always)]
49 fn device_handle(&self) -> VkDevice {
50 self.device.native_ptr()
51 }
52}
53impl<Device, Surface> DeviceChild for SurfaceSwapchainObject<Device, Surface>
54where
55 Device: crate::Device,
56 Surface: VkHandle<Handle = VkSurfaceKHR>,
57{
58 type ConcreteDevice = Device;
59
60 #[inline(always)]
61 fn device(&self) -> &Self::ConcreteDevice {
62 &self.device
63 }
64}
65impl<Device, Surface> Swapchain for SurfaceSwapchainObject<Device, Surface>
66where
67 Device: crate::Device,
68 Surface: VkHandle<Handle = VkSurfaceKHR>,
69{
70 #[inline(always)]
71 fn format(&self) -> VkFormat {
72 self.format
73 }
74
75 #[inline(always)]
76 fn size(&self) -> &VkExtent2D {
77 &self.extent
78 }
79}
80impl<Device, Surface> SurfaceSwapchainObject<Device, Surface>
81where
82 Device: VkHandle<Handle = VkDevice>,
83 Surface: VkHandle<Handle = VkSurfaceKHR>,
84{
85 #[implements]
87 pub fn deconstruct(self) -> (Device, Surface) {
88 let d = unsafe { core::ptr::read(&self.device) };
89 let s = unsafe { core::ptr::read(&self.surface) };
90
91 unsafe {
93 crate::vkfn::destroy_swapchain_khr(self.device.native_ptr(), self.handle, core::ptr::null());
94 }
95 core::mem::forget(self);
96
97 (d, s)
98 }
99}
100impl<Surface: crate::Surface> super::TransferSurfaceObject for SwapchainBuilder<'_, '_, Surface> {
101 type ConcreteSurface = Surface;
102
103 #[inline(always)]
104 fn transfer_surface(self) -> Self::ConcreteSurface {
105 self.1
106 }
107}
108
109pub struct SwapchainBuilder<'n, 'sw, Surface: crate::Surface>(
111 VkSwapchainCreateInfoKHR,
112 Surface,
113 core::marker::PhantomData<(
114 Option<&'n dyn VulkanStructure>,
115 Option<&'sw dyn VkHandle<Handle = VkSwapchainKHR>>,
116 )>,
117);
118impl<'n, 'sw, Surface: crate::Surface> SwapchainBuilder<'n, 'sw, Surface> {
119 pub fn new(
120 surface: Surface,
121 min_image_count: u32,
122 format: VkSurfaceFormatKHR,
123 extent: VkExtent2D,
124 usage: ImageUsageFlags,
125 ) -> Self {
126 Self(
127 VkSwapchainCreateInfoKHR {
128 sType: VkSwapchainCreateInfoKHR::TYPE,
129 pNext: core::ptr::null(),
130 flags: 0,
131 surface: surface.native_ptr(),
132 minImageCount: min_image_count,
133 imageFormat: format.format,
134 imageColorSpace: format.colorSpace,
135 imageExtent: extent,
136 imageArrayLayers: 1,
137 imageUsage: usage.bits(),
138 imageSharingMode: VK_SHARING_MODE_EXCLUSIVE,
139 preTransform: VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR,
140 compositeAlpha: VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
141 presentMode: PresentMode::FIFO as _,
142 queueFamilyIndexCount: 0,
143 pQueueFamilyIndices: core::ptr::null(),
144 clipped: false as _,
145 oldSwapchain: VkSwapchainKHR::NULL,
146 },
147 surface,
148 core::marker::PhantomData,
149 )
150 }
151
152 pub const fn with_next(mut self, next: &'n (impl VulkanStructure + ?Sized)) -> Self {
153 self.0.pNext = next as *const _ as _;
154 self
155 }
156
157 pub const fn array_layers(mut self, layers: u32) -> Self {
158 self.0.imageArrayLayers = layers;
159 self
160 }
161
162 pub const fn shared(mut self, queue_families: &[u32]) -> Self {
163 assert!(queue_families.len() > 0, "empty families not allowed");
164
165 self.0.imageSharingMode = if queue_families.is_empty() {
166 VK_SHARING_MODE_EXCLUSIVE
167 } else {
168 VK_SHARING_MODE_CONCURRENT
169 };
170 self.0.queueFamilyIndexCount = queue_families.len() as _;
171 self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(queue_families);
172 self
173 }
174
175 pub const fn exclusive(mut self) -> Self {
176 self.0.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
177 self.0.queueFamilyIndexCount = 0;
178 self.0.pQueueFamilyIndices = core::ptr::null();
179
180 self
181 }
182
183 pub const fn pre_transform(mut self, tf: VkSurfaceTransformFlagsKHR) -> Self {
185 self.0.preTransform = tf as _;
186 self
187 }
188
189 pub const fn composite_alpha(mut self, a: VkCompositeAlphaFlagsKHR) -> Self {
191 self.0.compositeAlpha = a as _;
192 self
193 }
194
195 pub const fn present_mode(mut self, mode: PresentMode) -> Self {
197 self.0.presentMode = mode as _;
198 self
199 }
200
201 pub const fn enable_clip(mut self) -> Self {
204 self.0.clipped = true as _;
205 self
206 }
207
208 #[inline(always)]
209 pub fn old_swapchain(mut self, sw: &'sw (impl VkHandle<Handle = VkSwapchainKHR> + ?Sized)) -> Self {
210 self.0.oldSwapchain = sw.native_ptr();
211 self
212 }
213
214 #[implements]
224 pub fn create<Device: crate::Device>(
225 mut self,
226 device: Device,
227 ) -> crate::Result<SurfaceSwapchainObject<Device, Surface>> {
228 let mut h = core::mem::MaybeUninit::uninit();
229 let mut structure = core::mem::MaybeUninit::uninit();
230 self.build(unsafe { &mut *structure.as_mut_ptr() });
231 let structure = unsafe { structure.assume_init() };
232
233 unsafe {
234 crate::vkfn::create_swapchain_khr(device.native_ptr(), &structure, std::ptr::null(), h.as_mut_ptr())
235 .into_result()
236 .map(|_| SurfaceSwapchainObject {
237 handle: h.assume_init(),
238 device,
239 surface: self.1,
240 format: structure.imageFormat,
241 extent: structure.imageExtent,
242 })
243 }
244 }
245}
246impl<Surface: crate::Surface> VulkanStructureProvider for SwapchainBuilder<'_, '_, Surface> {
247 type RootStructure = VkSwapchainCreateInfoKHR;
248
249 #[inline(always)]
250 fn build<'r, 's: 'r>(&'s mut self, root: &'s mut VkSwapchainCreateInfoKHR) -> &'r mut GenericVulkanStructure {
251 *root = self.0.clone();
252 root.as_generic_mut()
253 }
254}