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_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,
26 pub struct UnknownSurfacePlatform(pub api::VkIcdWsiPlatform);
28 impl fmt::Display for UnknownSurfacePlatform {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 write!(f, "unknown surface platform {:?}", self.0)
34 impl Error for UnknownSurfacePlatform {}
36 impl SurfacePlatform {
37 pub fn from(platform: api::VkIcdWsiPlatform) -> Result<Self, UnknownSurfacePlatform> {
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)),
50 pub fn get_surface_implementation(self) -> Cow<'static, dyn SurfaceImplementation> {
51 #[cfg(target_os = "linux")]
52 const XCB_SURFACE_IMPLEMENTATION: XcbSurfaceImplementation = XcbSurfaceImplementation;
54 #[cfg(target_os = "linux")]
55 SurfacePlatform::VK_ICD_WSI_PLATFORM_XCB => Cow::Borrowed(&XCB_SURFACE_IMPLEMENTATION),
56 _ => Cow::Owned(FallbackSurfaceImplementation(self).duplicate()),
61 impl From<SurfacePlatform> for api::VkIcdWsiPlatform {
62 fn from(platform: SurfacePlatform) -> api::VkIcdWsiPlatform {
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,
76 pub trait Swapchain: Any + Sync + Send + Debug {}
78 pub trait SurfaceImplementation: Any + Sync + Send + Debug {
79 fn get_platform(&self) -> SurfacePlatform;
80 unsafe fn get_surface_formats(
82 surface: api::VkSurfaceKHR,
83 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult>;
84 unsafe fn get_present_modes(
86 surface: api::VkSurfaceKHR,
87 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult>;
88 unsafe fn get_capabilities(
90 surface: api::VkSurfaceKHR,
91 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult>;
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>;
101 impl ToOwned for dyn SurfaceImplementation {
102 type Owned = Box<dyn SurfaceImplementation>;
103 fn to_owned(&self) -> Box<dyn SurfaceImplementation> {
109 pub struct FallbackSurfaceImplementation(SurfacePlatform);
111 impl FallbackSurfaceImplementation {
112 pub fn report_error(&self) -> ! {
114 "there is no surface implementation for {:?}",
120 impl SurfaceImplementation for FallbackSurfaceImplementation {
121 fn get_platform(&self) -> SurfacePlatform {
124 unsafe fn get_surface_formats(
126 _surface: api::VkSurfaceKHR,
127 ) -> Result<Cow<'static, [api::VkSurfaceFormatKHR]>, api::VkResult> {
130 unsafe fn get_present_modes(
132 _surface: api::VkSurfaceKHR,
133 ) -> Result<Cow<'static, [api::VkPresentModeKHR]>, api::VkResult> {
136 unsafe fn get_capabilities(
138 _surface: api::VkSurfaceKHR,
139 ) -> Result<api::VkSurfaceCapabilitiesKHR, api::VkResult> {
144 _create_info: &api::VkSwapchainCreateInfoKHR,
145 _device_group_create_info: Option<&api::VkDeviceGroupSwapchainCreateInfoKHR>,
146 ) -> Result<Box<Swapchain>, api::VkResult> {
149 unsafe fn destroy_surface(&self, _surface: NonNull<api::VkIcdSurfaceBase>) {
152 fn duplicate(&self) -> Box<dyn SurfaceImplementation> {
153 Box::new(FallbackSurfaceImplementation(self.0))