4221a313735ccc1beb8b0fbd0f777c0e91c117b4
[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_MIR,
16 VK_ICD_WSI_PLATFORM_WAYLAND,
17 VK_ICD_WSI_PLATFORM_WIN32,
18 VK_ICD_WSI_PLATFORM_XCB,
19 VK_ICD_WSI_PLATFORM_XLIB,
20 VK_ICD_WSI_PLATFORM_ANDROID,
21 VK_ICD_WSI_PLATFORM_MACOS,
22 VK_ICD_WSI_PLATFORM_IOS,
23 VK_ICD_WSI_PLATFORM_DISPLAY,
24 }
25
26 #[derive(Debug)]
27 pub struct UnknownSurfacePlatform(pub api::VkIcdWsiPlatform);
28
29 impl fmt::Display for UnknownSurfacePlatform {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 write!(f, "unknown surface platform {:?}", self.0)
32 }
33 }
34
35 impl Error for UnknownSurfacePlatform {}
36
37 impl SurfacePlatform {
38 pub fn from(platform: api::VkIcdWsiPlatform) -> Result<Self, UnknownSurfacePlatform> {
39 match platform {
40 api::VK_ICD_WSI_PLATFORM_MIR => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_MIR),
41 api::VK_ICD_WSI_PLATFORM_WAYLAND => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_WAYLAND),
42 api::VK_ICD_WSI_PLATFORM_WIN32 => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_WIN32),
43 api::VK_ICD_WSI_PLATFORM_XCB => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB),
44 api::VK_ICD_WSI_PLATFORM_XLIB => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_XLIB),
45 api::VK_ICD_WSI_PLATFORM_ANDROID => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_ANDROID),
46 api::VK_ICD_WSI_PLATFORM_MACOS => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_MACOS),
47 api::VK_ICD_WSI_PLATFORM_IOS => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_IOS),
48 api::VK_ICD_WSI_PLATFORM_DISPLAY => Ok(SurfacePlatform::VK_ICD_WSI_PLATFORM_DISPLAY),
49 platform => Err(UnknownSurfacePlatform(platform)),
50 }
51 }
52 pub fn get_surface_implementation(self) -> Cow<'static, dyn SurfaceImplementation> {
53 #[cfg(target_os = "linux")]
54 const XCB_SURFACE_IMPLEMENTATION: XcbSurfaceImplementation = XcbSurfaceImplementation;
55 match self {
56 #[cfg(target_os = "linux")]
57 SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB => Cow::Borrowed(&XCB_SURFACE_IMPLEMENTATION),
58 _ => Cow::Owned(FallbackSurfaceImplementation(self).duplicate()),
59 }
60 }
61 }
62
63 impl From<SurfacePlatform> for api::VkIcdWsiPlatform {
64 fn from(platform: SurfacePlatform) -> api::VkIcdWsiPlatform {
65 match platform {
66 SurfacePlatform::VK_ICD_WSI_PLATFORM_MIR => api::VK_ICD_WSI_PLATFORM_MIR,
67 SurfacePlatform::VK_ICD_WSI_PLATFORM_WAYLAND => api::VK_ICD_WSI_PLATFORM_WAYLAND,
68 SurfacePlatform::VK_ICD_WSI_PLATFORM_WIN32 => api::VK_ICD_WSI_PLATFORM_WIN32,
69 SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB => api::VK_ICD_WSI_PLATFORM_XCB,
70 SurfacePlatform::VK_ICD_WSI_PLATFORM_XLIB => api::VK_ICD_WSI_PLATFORM_XLIB,
71 SurfacePlatform::VK_ICD_WSI_PLATFORM_ANDROID => api::VK_ICD_WSI_PLATFORM_ANDROID,
72 SurfacePlatform::VK_ICD_WSI_PLATFORM_MACOS => api::VK_ICD_WSI_PLATFORM_MACOS,
73 SurfacePlatform::VK_ICD_WSI_PLATFORM_IOS => api::VK_ICD_WSI_PLATFORM_IOS,
74 SurfacePlatform::VK_ICD_WSI_PLATFORM_DISPLAY => api::VK_ICD_WSI_PLATFORM_DISPLAY,
75 }
76 }
77 }
78
79 pub trait Swapchain: Any + Sync + Send + Debug {}
80
81 pub trait SurfaceImplementation: Any + Sync + Send + Debug {
82 fn get_platform(&self) -> SurfacePlatform;
83 unsafe fn get_surface_formats(
84 &self,
85 surface: api::VkSurfaceKHR,
86 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult>;
87 unsafe fn get_present_modes(
88 &self,
89 surface: api::VkSurfaceKHR,
90 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult>;
91 unsafe fn get_capabilities(
92 &self,
93 surface: api::VkSurfaceKHR,
94 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult>;
95 unsafe fn build(
96 &self,
97 create_info: &api::VkSwapchainCreateInfoKHR,
98 device_group_create_info: Option<&api::VkDeviceGroupSwapchainCreateInfoKHR>,
99 ) -> Result<Box<Swapchain>, api::VkResult>;
100 unsafe fn destroy_surface(&self, surface: NonNull<api::VkIcdSurfaceBase>);
101 fn duplicate(&self) -> Box<dyn SurfaceImplementation>;
102 }
103
104 impl ToOwned for dyn SurfaceImplementation {
105 type Owned = Box<dyn SurfaceImplementation>;
106 fn to_owned(&self) -> Box<dyn SurfaceImplementation> {
107 self.duplicate()
108 }
109 }
110
111 #[derive(Debug)]
112 pub struct FallbackSurfaceImplementation(SurfacePlatform);
113
114 impl FallbackSurfaceImplementation {
115 pub fn report_error(&self) -> ! {
116 panic!(
117 "there is no surface implementation for {:?}",
118 self.get_platform()
119 )
120 }
121 }
122
123 impl SurfaceImplementation for FallbackSurfaceImplementation {
124 fn get_platform(&self) -> SurfacePlatform {
125 self.0
126 }
127 unsafe fn get_surface_formats(
128 &self,
129 _surface: api::VkSurfaceKHR,
130 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult> {
131 self.report_error()
132 }
133 unsafe fn get_present_modes(
134 &self,
135 _surface: api::VkSurfaceKHR,
136 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult> {
137 self.report_error()
138 }
139 unsafe fn get_capabilities(
140 &self,
141 _surface: api::VkSurfaceKHR,
142 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult> {
143 self.report_error()
144 }
145 unsafe fn build(
146 &self,
147 _create_info: &api::VkSwapchainCreateInfoKHR,
148 _device_group_create_info: Option<&api::VkDeviceGroupSwapchainCreateInfoKHR>,
149 ) -> Result<Box<Swapchain>, api::VkResult> {
150 self.report_error()
151 }
152 unsafe fn destroy_surface(&self, _surface: NonNull<api::VkIcdSurfaceBase>) {
153 self.report_error()
154 }
155 fn duplicate(&self) -> Box<dyn SurfaceImplementation> {
156 Box::new(FallbackSurfaceImplementation(self.0))
157 }
158 }