vulk_ext/vkx/
surface.rs

1use super::*;
2
3use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
4
5#[derive(Debug)]
6pub struct Surface {
7    surface: vk::SurfaceKHR,
8    pub create_info: vk::Win32SurfaceCreateInfoKHR,
9    pub surface_capabilities: vk::SurfaceCapabilitiesKHR,
10    pub surface_formats: Vec<vk::SurfaceFormatKHR>,
11    pub surface_format: vk::SurfaceFormatKHR,
12    pub present_modes: Vec<vk::PresentModeKHR>,
13    pub present_mode: vk::PresentModeKHR,
14}
15
16impl Surface {
17    #[cfg(target_family = "windows")]
18    pub unsafe fn create<Window>(
19        instance: &Instance,
20        physical_device: &PhysicalDevice,
21        window: &Window,
22    ) -> Result<Self>
23    where
24        Window: HasRawDisplayHandle + HasRawWindowHandle,
25    {
26        use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
27
28        // Surface.
29        let display_handle = window.raw_display_handle();
30        let window_handle = window.raw_window_handle();
31        let create_info = match (display_handle, window_handle) {
32            (RawDisplayHandle::Windows(_), RawWindowHandle::Win32(window)) => {
33                vk::Win32SurfaceCreateInfoKHR {
34                    s_type: vk::StructureType::Win32SurfaceCreateInfoKHR,
35                    p_next: null(),
36                    flags: vk::Win32SurfaceCreateFlagsKHR::empty(),
37                    hinstance: window.hinstance,
38                    hwnd: window.hwnd,
39                }
40            }
41            _ => {
42                bail!("Unsupported platform: display_handle={display_handle:?}, window_handle={window_handle:?}");
43            }
44        };
45        let surface = instance.create_win32_surface_khr(&create_info)?;
46
47        // Surface capabilities.
48        let surface_capabilities = instance
49            .get_physical_device_surface_capabilities_khr(physical_device.handle(), surface)?;
50
51        // Surface formats.
52        let surface_formats = vulk::read_to_vec(
53            |count, ptr| {
54                instance.get_physical_device_surface_formats_khr(
55                    physical_device.handle(),
56                    surface,
57                    count,
58                    ptr,
59                )
60            },
61            None,
62        )?;
63        let surface_format = *surface_formats
64            .iter()
65            .find(|f| f.format == vk::Format::B8g8r8a8Unorm)
66            .context("Finding surface format")?;
67
68        // Present modes.
69        let present_modes = vulk::read_to_vec(
70            |count, ptr| {
71                instance.get_physical_device_surface_present_modes_khr(
72                    physical_device.handle(),
73                    surface,
74                    count,
75                    ptr,
76                )
77            },
78            None,
79        )?;
80        let present_mode = *present_modes
81            .iter()
82            .find(|&&p| p == vk::PresentModeKHR::FifoKHR)
83            .context("Finding present mode")?;
84
85        Ok(Self {
86            surface,
87            create_info,
88            surface_capabilities,
89            surface_formats,
90            surface_format,
91            present_modes,
92            present_mode,
93        })
94    }
95
96    #[cfg(not(target_family = "windows"))]
97    pub unsafe fn create<Window>(
98        _instance: &Instance,
99        _physical_device: &PhysicalDevice,
100        _window: &Window,
101    ) -> Result<Self>
102    where
103        Window: HasRawDisplayHandle + HasRawWindowHandle,
104    {
105        todo!("Unsupported platform");
106    }
107
108    pub unsafe fn destroy(self, instance: &Instance) {
109        instance.destroy_surface_khr(self.surface);
110    }
111
112    #[must_use]
113    pub fn handle(&self) -> vk::SurfaceKHR {
114        self.surface
115    }
116}