remove MIR support since Vulkan is dropping support
[kazan.git] / vulkan-driver / src / swapchain.rs
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
3 use api;
4 use std::any::Any;
5 use std::borrow::Cow;
6 use std::error::Error;
7 use std::fmt::{self, Debug};
8 use std::ptr::NonNull;
9 #[cfg(target_os = "linux")]
10 use xcb_swapchain::XcbSurfaceImplementation;
11
12 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Enum)]
13 #[allow(non_camel_case_types)]
14 pub enum SurfacePlatform {
15 VK_ICD_WSI_PLATFORM_WAYLAND,
16 VK_ICD_WSI_PLATFORM_WIN32,
17 VK_ICD_WSI_PLATFORM_XCB,
18 VK_ICD_WSI_PLATFORM_XLIB,
19 VK_ICD_WSI_PLATFORM_ANDROID,
20 VK_ICD_WSI_PLATFORM_MACOS,
21 VK_ICD_WSI_PLATFORM_IOS,
22 VK_ICD_WSI_PLATFORM_DISPLAY,
23 }
24
25 #[derive(Debug)]
26 pub struct UnknownSurfacePlatform(pub api::VkIcdWsiPlatform);
27
28 impl fmt::Display for UnknownSurfacePlatform {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 write!(f, "unknown surface platform {:?}", self.0)
31 }
32 }
33
34 impl Error for UnknownSurfacePlatform {}
35
36 impl SurfacePlatform {
37 pub fn from(platform: api::VkIcdWsiPlatform) -> Result<Self, UnknownSurfacePlatform> {
38 match platform {
39 api::VK_ICD_WSI_PLATFORM_WAYLAND => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_WAYLAND),
40 api::VK_ICD_WSI_PLATFORM_WIN32 => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_WIN32),
41 api::VK_ICD_WSI_PLATFORM_XCB => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB),
42 api::VK_ICD_WSI_PLATFORM_XLIB => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_XLIB),
43 api::VK_ICD_WSI_PLATFORM_ANDROID => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_ANDROID),
44 api::VK_ICD_WSI_PLATFORM_MACOS => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_MACOS),
45 api::VK_ICD_WSI_PLATFORM_IOS => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_IOS),
46 api::VK_ICD_WSI_PLATFORM_DISPLAY => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_DISPLAY),
47 platform => Err(UnknownSurfacePlatform(platform)),
48 }
49 }
50 pub fn get_surface_implementation(self) -> Cow<'static, dyn SurfaceImplementation> {
51 #[cfg(target_os = "linux")]
52 const XCB_SURFACE_IMPLEMENTATION: XcbSurfaceImplementation = XcbSurfaceImplementation;
53 match self {
54 #[cfg(target_os = "linux")]
55 SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB => Cow::Borrowed(&XCB_SURFACE_IMPLEMENTATION),
56 _ => Cow::Owned(FallbackSurfaceImplementation(self).duplicate()),
57 }
58 }
59 }
60
61 impl From<SurfacePlatform> for api::VkIcdWsiPlatform {
62 fn from(platform: SurfacePlatform) -> api::VkIcdWsiPlatform {
63 match platform {
64 SurfacePlatform::VK_ICD_WSI_PLATFORM_WAYLAND => api::VK_ICD_WSI_PLATFORM_WAYLAND,
65 SurfacePlatform::VK_ICD_WSI_PLATFORM_WIN32 => api::VK_ICD_WSI_PLATFORM_WIN32,
66 SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB => api::VK_ICD_WSI_PLATFORM_XCB,
67 SurfacePlatform::VK_ICD_WSI_PLATFORM_XLIB => api::VK_ICD_WSI_PLATFORM_XLIB,
68 SurfacePlatform::VK_ICD_WSI_PLATFORM_ANDROID => api::VK_ICD_WSI_PLATFORM_ANDROID,
69 SurfacePlatform::VK_ICD_WSI_PLATFORM_MACOS => api::VK_ICD_WSI_PLATFORM_MACOS,
70 SurfacePlatform::VK_ICD_WSI_PLATFORM_IOS => api::VK_ICD_WSI_PLATFORM_IOS,
71 SurfacePlatform::VK_ICD_WSI_PLATFORM_DISPLAY => api::VK_ICD_WSI_PLATFORM_DISPLAY,
72 }
73 }
74 }
75
76 pub trait Swapchain: Any + Sync + Send + Debug {}
77
78 pub trait SurfaceImplementation: Any + Sync + Send + Debug {
79 fn get_platform(&self) -> SurfacePlatform;
80 unsafe fn get_surface_formats(
81 &self,
82 surface: api::VkSurfaceKHR,
83 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult>;
84 unsafe fn get_present_modes(
85 &self,
86 surface: api::VkSurfaceKHR,
87 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult>;
88 unsafe fn get_capabilities(
89 &self,
90 surface: api::VkSurfaceKHR,
91 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult>;
92 unsafe fn build(
93 &self,
94 create_info: &api::VkSwapchainCreateInfoKHR,
95 device_group_create_info: Option<&api::VkDeviceGroupSwapchainCreateInfoKHR>,
96 ) -> Result<Box<Swapchain>, api::VkResult>;
97 unsafe fn destroy_surface(&self, surface: NonNull<api::VkIcdSurfaceBase>);
98 fn duplicate(&self) -> Box<dyn SurfaceImplementation>;
99 }
100
101 impl ToOwned for dyn SurfaceImplementation {
102 type Owned = Box<dyn SurfaceImplementation>;
103 fn to_owned(&self) -> Box<dyn SurfaceImplementation> {
104 self.duplicate()
105 }
106 }
107
108 #[derive(Debug)]
109 pub struct FallbackSurfaceImplementation(SurfacePlatform);
110
111 impl FallbackSurfaceImplementation {
112 pub fn report_error(&self) -> ! {
113 panic!(
114 "there is no surface implementation for {:?}",
115 self.get_platform()
116 )
117 }
118 }
119
120 impl SurfaceImplementation for FallbackSurfaceImplementation {
121 fn get_platform(&self) -> SurfacePlatform {
122 self.0
123 }
124 unsafe fn get_surface_formats(
125 &self,
126 _surface: api::VkSurfaceKHR,
127 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult> {
128 self.report_error()
129 }
130 unsafe fn get_present_modes(
131 &self,
132 _surface: api::VkSurfaceKHR,
133 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult> {
134 self.report_error()
135 }
136 unsafe fn get_capabilities(
137 &self,
138 _surface: api::VkSurfaceKHR,
139 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult> {
140 self.report_error()
141 }
142 unsafe fn build(
143 &self,
144 _create_info: &api::VkSwapchainCreateInfoKHR,
145 _device_group_create_info: Option<&api::VkDeviceGroupSwapchainCreateInfoKHR>,
146 ) -> Result<Box<Swapchain>, api::VkResult> {
147 self.report_error()
148 }
149 unsafe fn destroy_surface(&self, _surface: NonNull<api::VkIcdSurfaceBase>) {
150 self.report_error()
151 }
152 fn duplicate(&self) -> Box<dyn SurfaceImplementation> {
153 Box::new(FallbackSurfaceImplementation(self.0))
154 }
155 }