Skip to main content

bedrock/surface/
swapchain_surface_integrated.rs

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/// Opaque handle to as swapchain object, backed with specific surface
9#[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    /// Deconstructs this and take ownership of managed objects(no drop occured)
106    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    /// Deconstructs the swapchain and retrieves its parents
116    #[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        // Note: DeviceとSurfaceをdropさせない(Swapchainだけ消す)
122        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
139/// Builder object to construct a `Swapchain`, backed with a surface
140pub 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    /// Default: Inherit
211    pub const fn pre_transform(mut self, tf: SurfaceTransformFlags) -> Self {
212        self.0.preTransform = tf.bits();
213        self
214    }
215
216    /// Default: Inherit
217    pub const fn composite_alpha(mut self, a: CompositeAlphaFlags) -> Self {
218        self.0.compositeAlpha = a.bits();
219        self
220    }
221
222    /// Default: FIFO
223    pub const fn present_mode(mut self, mode: PresentMode) -> Self {
224        self.0.presentMode = mode as _;
225        self
226    }
227
228    /// Enables whether the Vulkan implementation is allowed to discard rendering operations
229    /// that affect regions of the surface which aren't visible
230    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    /// Create a swapchain
242    /// # Failures
243    /// On failure, this command returns
244    ///
245    /// * `brvk::VK_ERROR_OUT_OF_HOST_MEMORY`
246    /// * `brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`
247    /// * `brvk::VK_ERROR_DEVICE_LOST`
248    /// * `brvk::VK_ERROR_SURFACE_LOST_KHR`
249    /// * `brvk::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`
250    #[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}