bevy_mod_openxr/openxr/
error.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use super::graphics::GraphicsBackend;
5
6use thiserror::Error;
7
8#[derive(Error, Debug)]
9pub enum OxrError {
10    #[error("OpenXR error: {0}")]
11    OpenXrError(#[from] openxr::sys::Result),
12    #[error("OpenXR loading error: {0}")]
13    OpenXrLoadingError(#[from] openxr::LoadError),
14    #[error("WGPU instance error: {0}")]
15    WgpuInstanceError(#[from] wgpu_hal::InstanceError),
16    #[error("WGPU device error: {0}")]
17    WgpuDeviceError(#[from] wgpu_hal::DeviceError),
18    #[error("WGPU request device error: {0}")]
19    WgpuRequestDeviceError(#[from] wgpu::RequestDeviceError),
20    #[error("Unsupported texture format: {0:?}")]
21    UnsupportedTextureFormat(wgpu::TextureFormat),
22    #[error("Graphics backend '{0:?}' is not available")]
23    UnavailableBackend(GraphicsBackend),
24    #[error("No compatible backend available")]
25    NoAvailableBackend,
26    #[error("No compatible view configuration available")]
27    NoAvailableViewConfiguration,
28    #[error("No compatible blend mode available")]
29    NoAvailableBlendMode,
30    #[error("No compatible format available")]
31    NoAvailableFormat,
32    #[error("OpenXR runtime does not support these extensions: {0}")]
33    UnavailableExtensions(UnavailableExts),
34    #[error("Could not meet graphics requirements for platform. See console for details")]
35    FailedGraphicsRequirements,
36    #[error(
37        "Tried to use item {item} with backend {backend}. Expected backend {expected_backend}"
38    )]
39    GraphicsBackendMismatch {
40        item: &'static str,
41        backend: &'static str,
42        expected_backend: &'static str,
43    },
44    #[error("Failed to create CString: {0}")]
45    NulError(#[from] std::ffi::NulError),
46    #[error("Graphics init error: {0}")]
47    InitError(InitError),
48}
49
50pub use init_error::InitError;
51
52/// This module is needed because thiserror does not allow conditional compilation within enums for some reason,
53/// so graphics api specific errors are implemented here.
54mod init_error {
55    use super::OxrError;
56    use std::fmt;
57
58    #[derive(Debug)]
59    pub enum InitError {
60        #[cfg(feature = "vulkan")]
61        VulkanError(ash::vk::Result),
62        #[cfg(feature = "vulkan")]
63        VulkanLoadingError(ash::LoadingError),
64        #[cfg(all(feature = "d3d12", windows))]
65        FailedToFindD3D12Adapter,
66    }
67
68    impl fmt::Display for InitError {
69        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70            match self {
71                #[cfg(feature = "vulkan")]
72                InitError::VulkanError(error) => write!(f, "Vulkan error: {}", error),
73                #[cfg(feature = "vulkan")]
74                InitError::VulkanLoadingError(error) => {
75                    write!(f, "Vulkan loading error: {}", error)
76                }
77                #[cfg(all(feature = "d3d12", windows))]
78                InitError::FailedToFindD3D12Adapter => write!(
79                    f,
80                    "Failed to find D3D12 adapter matching LUID provided by the OpenXR runtime"
81                ),
82            }
83        }
84    }
85
86    #[cfg(feature = "vulkan")]
87    impl From<ash::vk::Result> for OxrError {
88        fn from(value: ash::vk::Result) -> Self {
89            Self::InitError(InitError::VulkanError(value))
90        }
91    }
92
93    #[cfg(feature = "vulkan")]
94    impl From<ash::LoadingError> for OxrError {
95        fn from(value: ash::LoadingError) -> Self {
96            Self::InitError(InitError::VulkanLoadingError(value))
97        }
98    }
99}
100
101impl From<Vec<Cow<'static, str>>> for OxrError {
102    fn from(value: Vec<Cow<'static, str>>) -> Self {
103        Self::UnavailableExtensions(UnavailableExts(value))
104    }
105}
106
107#[derive(Debug)]
108pub struct UnavailableExts(Vec<Cow<'static, str>>);
109
110impl fmt::Display for UnavailableExts {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        for s in &self.0 {
113            write!(f, "\t{s}")?;
114        }
115        Ok(())
116    }
117}