bedrock/surface/
swapchain_surface_integrated.rs

1use crate::ffi_helper::slice_as_ptr_empty_null;
2use crate::*;
3use derives::implements;
4
5use super::DeviceChildHandle;
6
7/// Opaque handle to as swapchain object, backed with specific surface
8#[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    /// Deconstructs the swapchain and retrieves its parents
86    #[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        // Note: DeviceとSurfaceをdropさせない(Swapchainだけ消す)
92        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
109/// Builder object to construct a `Swapchain`, backed with a surface
110pub 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    /// Default: Inherit
184    pub const fn pre_transform(mut self, tf: VkSurfaceTransformFlagsKHR) -> Self {
185        self.0.preTransform = tf as _;
186        self
187    }
188
189    /// Default: Inherit
190    pub const fn composite_alpha(mut self, a: VkCompositeAlphaFlagsKHR) -> Self {
191        self.0.compositeAlpha = a as _;
192        self
193    }
194
195    /// Default: FIFO
196    pub const fn present_mode(mut self, mode: PresentMode) -> Self {
197        self.0.presentMode = mode as _;
198        self
199    }
200
201    /// Enables whether the Vulkan implementation is allowed to discard rendering operations
202    /// that affect regions of the surface which aren't visible
203    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    /// Create a swapchain
215    /// # Failures
216    /// On failure, this command returns
217    ///
218    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
219    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
220    /// * `VK_ERROR_DEVICE_LOST`
221    /// * `VK_ERROR_SURFACE_LOST_KHR`
222    /// * `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`
223    #[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}