ash/extensions/khr/
swapchain.rs

1use crate::prelude::*;
2use crate::vk;
3use crate::RawPtr;
4use crate::{Device, Instance};
5use std::ffi::CStr;
6use std::mem;
7
8#[derive(Clone)]
9pub struct Swapchain {
10    handle: vk::Device,
11    fp: vk::KhrSwapchainFn,
12}
13
14impl Swapchain {
15    pub fn new(instance: &Instance, device: &Device) -> Self {
16        let handle = device.handle();
17        let fp = vk::KhrSwapchainFn::load(|name| unsafe {
18            mem::transmute(instance.get_device_proc_addr(handle, name.as_ptr()))
19        });
20        Self { handle, fp }
21    }
22
23    /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkDestroySwapchainKHR.html>
24    pub unsafe fn destroy_swapchain(
25        &self,
26        swapchain: vk::SwapchainKHR,
27        allocation_callbacks: Option<&vk::AllocationCallbacks>,
28    ) {
29        (self.fp.destroy_swapchain_khr)(self.handle, swapchain, allocation_callbacks.as_raw_ptr());
30    }
31
32    /// On success, returns the next image's index and whether the swapchain is suboptimal for the surface.
33    /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkAcquireNextImageKHR.html>
34    pub unsafe fn acquire_next_image(
35        &self,
36        swapchain: vk::SwapchainKHR,
37        timeout: u64,
38        semaphore: vk::Semaphore,
39        fence: vk::Fence,
40    ) -> VkResult<(u32, bool)> {
41        let mut index = 0;
42        let err_code = (self.fp.acquire_next_image_khr)(
43            self.handle,
44            swapchain,
45            timeout,
46            semaphore,
47            fence,
48            &mut index,
49        );
50        match err_code {
51            vk::Result::SUCCESS => Ok((index, false)),
52            vk::Result::SUBOPTIMAL_KHR => Ok((index, true)),
53            _ => Err(err_code),
54        }
55    }
56
57    /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateSwapchainKHR.html>
58    pub unsafe fn create_swapchain(
59        &self,
60        create_info: &vk::SwapchainCreateInfoKHR,
61        allocation_callbacks: Option<&vk::AllocationCallbacks>,
62    ) -> VkResult<vk::SwapchainKHR> {
63        let mut swapchain = mem::zeroed();
64        (self.fp.create_swapchain_khr)(
65            self.handle,
66            create_info,
67            allocation_callbacks.as_raw_ptr(),
68            &mut swapchain,
69        )
70        .result_with_success(swapchain)
71    }
72
73    /// On success, returns whether the swapchain is suboptimal for the surface.
74    /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkQueuePresentKHR.html>
75    pub unsafe fn queue_present(
76        &self,
77        queue: vk::Queue,
78        present_info: &vk::PresentInfoKHR,
79    ) -> VkResult<bool> {
80        let err_code = (self.fp.queue_present_khr)(queue, present_info);
81        match err_code {
82            vk::Result::SUCCESS => Ok(false),
83            vk::Result::SUBOPTIMAL_KHR => Ok(true),
84            _ => Err(err_code),
85        }
86    }
87
88    /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetSwapchainImagesKHR.html>
89    pub unsafe fn get_swapchain_images(
90        &self,
91        swapchain: vk::SwapchainKHR,
92    ) -> VkResult<Vec<vk::Image>> {
93        read_into_uninitialized_vector(|count, data| {
94            (self.fp.get_swapchain_images_khr)(self.handle, swapchain, count, data)
95        })
96    }
97
98    pub const fn name() -> &'static CStr {
99        vk::KhrSwapchainFn::name()
100    }
101
102    pub fn fp(&self) -> &vk::KhrSwapchainFn {
103        &self.fp
104    }
105
106    pub fn device(&self) -> vk::Device {
107        self.handle
108    }
109}