1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
7 use std::fmt::{self, Debug};
9 #[cfg(target_os = "linux")]
10 use xcb_swapchain::XcbSurfaceImplementation;
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,
27 pub struct UnknownSurfacePlatform(pub api::VkIcdWsiPlatform);
29 impl fmt::Display for UnknownSurfacePlatform {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 write!(f, "unknown surface platform {:?}", self.0)
35 impl Error for UnknownSurfacePlatform {}
37 impl SurfacePlatform {
38 pub fn from(platform: api::VkIcdWsiPlatform) -> Result<Self, UnknownSurfacePlatform> {
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)),
52 pub fn get_surface_implementation(self) -> Cow<'static, dyn SurfaceImplementation> {
53 #[cfg(target_os = "linux")]
54 const XCB_SURFACE_IMPLEMENTATION: XcbSurfaceImplementation = XcbSurfaceImplementation;
56 #[cfg(target_os = "linux")]
57 SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB => Cow::Borrowed(&XCB_SURFACE_IMPLEMENTATION),
58 _ => Cow::Owned(FallbackSurfaceImplementation(self).duplicate()),
63 impl From<SurfacePlatform> for api::VkIcdWsiPlatform {
64 fn from(platform: SurfacePlatform) -> api::VkIcdWsiPlatform {
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,
79 pub trait Swapchain: Any + Sync + Send + Debug {}
81 pub trait SurfaceImplementation: Any + Sync + Send + Debug {
82 fn get_platform(&self) -> SurfacePlatform;
83 unsafe fn get_surface_formats(
85 surface: api::VkSurfaceKHR,
86 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult>;
87 unsafe fn get_present_modes(
89 surface: api::VkSurfaceKHR,
90 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult>;
91 unsafe fn get_capabilities(
93 surface: api::VkSurfaceKHR,
94 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult>;
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>;
104 impl ToOwned for dyn SurfaceImplementation {
105 type Owned = Box<dyn SurfaceImplementation>;
106 fn to_owned(&self) -> Box<dyn SurfaceImplementation> {
112 pub struct FallbackSurfaceImplementation(SurfacePlatform);
114 impl FallbackSurfaceImplementation {
115 pub fn report_error(&self) -> ! {
117 "there is no surface implementation for {:?}",
123 impl SurfaceImplementation for FallbackSurfaceImplementation {
124 fn get_platform(&self) -> SurfacePlatform {
127 unsafe fn get_surface_formats(
129 _surface: api::VkSurfaceKHR,
130 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult> {
133 unsafe fn get_present_modes(
135 _surface: api::VkSurfaceKHR,
136 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult> {
139 unsafe fn get_capabilities(
141 _surface: api::VkSurfaceKHR,
142 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult> {
147 _create_info: &api::VkSwapchainCreateInfoKHR,
148 _device_group_create_info: Option<&api::VkDeviceGroupSwapchainCreateInfoKHR>,
149 ) -> Result<Box<Swapchain>, api::VkResult> {
152 unsafe fn destroy_surface(&self, _surface: NonNull<api::VkIcdSurfaceBase>) {
155 fn duplicate(&self) -> Box<dyn SurfaceImplementation> {
156 Box::new(FallbackSurfaceImplementation(self.0))