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 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 let surface_capabilities = instance
49 .get_physical_device_surface_capabilities_khr(physical_device.handle(), surface)?;
50
51 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 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}