ailloli_ui_openxr/openxr_runtime/error.rs
1//! Failures produced while initializing or driving OpenXR and Vulkan.
2
3use openxr as xr;
4
5#[derive(Debug, thiserror::Error)]
6/// Error returned by the native OpenXR runtime path.
7///
8/// Variants retain the native OpenXR or Vulkan result whenever one is available;
9/// configuration and loader failures retain descriptive context instead.
10///
11/// # Examples
12///
13/// ```
14/// use ailloli_ui_openxr::OpenXrRuntimeError;
15/// let error = OpenXrRuntimeError::MissingExtension("XR_KHR_vulkan_enable2");
16/// assert!(error.to_string().contains("XR_KHR_vulkan_enable2"));
17/// ```
18pub enum OpenXrRuntimeError {
19 /// The platform OpenXR loader could not be opened.
20 #[error("failed to load OpenXR loader: {message}")]
21 LoadEntry {
22 /// Loader error text.
23 message: String,
24 },
25
26 #[cfg(target_os = "android")]
27 /// Android loader initialization failed.
28 #[error("failed to initialize OpenXR Android loader: {result:?}")]
29 InitializeAndroidLoader {
30 /// Native OpenXR result code.
31 result: xr::sys::Result,
32 },
33
34 /// Available extension enumeration failed.
35 #[error("failed to enumerate OpenXR extensions: {result:?}")]
36 EnumerateExtensions {
37 /// Native OpenXR result code.
38 result: xr::sys::Result,
39 },
40
41 /// A mandatory runtime extension was unavailable.
42 #[error("missing required OpenXR extension: {0}")]
43 MissingExtension(&'static str),
44
45 /// An application or engine name violated OpenXR byte constraints.
46 #[error("invalid OpenXR {field}: {reason}")]
47 InvalidOpenXrName {
48 /// Name field being validated.
49 field: &'static str,
50 /// NUL or byte-length violation.
51 reason: String,
52 },
53
54 /// Instance creation failed.
55 #[error("failed to create OpenXR instance: {result:?}")]
56 CreateInstance {
57 /// Native OpenXR result code.
58 result: xr::sys::Result,
59 },
60
61 /// Runtime property lookup failed.
62 #[error("failed to query OpenXR instance properties: {result:?}")]
63 InstanceProperties {
64 /// Native OpenXR result code.
65 result: xr::sys::Result,
66 },
67
68 /// No head-mounted-display system could be obtained.
69 #[error("failed to get OpenXR HMD system: {result:?}")]
70 System {
71 /// Native OpenXR result code.
72 result: xr::sys::Result,
73 },
74
75 /// Environment blend-mode enumeration failed.
76 #[error("failed to enumerate OpenXR blend modes: {result:?}")]
77 BlendModes {
78 /// Native OpenXR result code.
79 result: xr::sys::Result,
80 },
81
82 /// Vulkan graphics-requirement lookup failed.
83 #[error("failed to query OpenXR Vulkan graphics requirements: {result:?}")]
84 GraphicsRequirements {
85 /// Native OpenXR result code.
86 result: xr::sys::Result,
87 },
88
89 /// Requested Vulkan API version falls outside the runtime range.
90 #[error(
91 "OpenXR runtime does not support requested Vulkan API {requested}; supported min={min}, max={max}"
92 )]
93 UnsupportedVulkanVersion {
94 /// Vulkan version requested by Ailloli.
95 requested: xr::Version,
96 /// Minimum version accepted by the runtime.
97 min: xr::Version,
98 /// Maximum version accepted by the runtime.
99 max: xr::Version,
100 },
101
102 /// The Vulkan loader could not be opened.
103 #[error("failed to load Vulkan loader: {message}")]
104 LoadVulkanEntry {
105 /// Loader error text.
106 message: String,
107 },
108
109 /// A Vulkan application, engine, or layer name contained an invalid byte.
110 #[error("invalid Vulkan {field}: {message}")]
111 InvalidVulkanName {
112 /// Name field being converted.
113 field: &'static str,
114 /// Conversion failure text.
115 message: String,
116 },
117
118 /// OpenXR rejected Vulkan instance creation.
119 #[error("OpenXR failed to create Vulkan instance: {result:?}")]
120 CreateVulkanInstance {
121 /// Native OpenXR result code.
122 result: xr::sys::Result,
123 },
124
125 /// Vulkan itself rejected instance creation requested through OpenXR.
126 #[error("Vulkan instance creation through OpenXR failed: {result:?}")]
127 CreateVulkanInstanceVk {
128 /// Native Vulkan result code.
129 result: ash::vk::Result,
130 },
131
132 /// The runtime's Vulkan physical-device lookup failed.
133 #[error("failed to query OpenXR-selected Vulkan graphics device: {result:?}")]
134 VulkanGraphicsDevice {
135 /// Native OpenXR result code.
136 result: xr::sys::Result,
137 },
138
139 /// No queue family advertised graphics support.
140 #[error("no Vulkan graphics queue family is available")]
141 NoGraphicsQueueFamily,
142
143 /// OpenXR rejected Vulkan logical-device creation.
144 #[error("OpenXR failed to create Vulkan device: {result:?}")]
145 CreateVulkanDevice {
146 /// Native OpenXR result code.
147 result: xr::sys::Result,
148 },
149
150 /// Vulkan rejected logical-device creation requested through OpenXR.
151 #[error("Vulkan device creation through OpenXR failed: {result:?}")]
152 CreateVulkanDeviceVk {
153 /// Native Vulkan result code.
154 result: ash::vk::Result,
155 },
156
157 /// Vulkan command-pool allocation failed.
158 #[error("failed to create Vulkan command pool: {result:?}")]
159 CreateCommandPool {
160 /// Native Vulkan result code.
161 result: ash::vk::Result,
162 },
163
164 /// Vulkan command-buffer allocation failed.
165 #[error("failed to allocate Vulkan command buffer: {result:?}")]
166 AllocateCommandBuffer {
167 /// Native Vulkan result code.
168 result: ash::vk::Result,
169 },
170
171 /// Beginning a one-time Vulkan command buffer failed.
172 #[error("failed to begin Vulkan command buffer: {result:?}")]
173 BeginCommandBuffer {
174 /// Native Vulkan result code.
175 result: ash::vk::Result,
176 },
177
178 /// Ending a one-time Vulkan command buffer failed.
179 #[error("failed to end Vulkan command buffer: {result:?}")]
180 EndCommandBuffer {
181 /// Native Vulkan result code.
182 result: ash::vk::Result,
183 },
184
185 /// Queue submission of recorded Vulkan work failed.
186 #[error("failed to submit Vulkan queue: {result:?}")]
187 QueueSubmit {
188 /// Native Vulkan result code.
189 result: ash::vk::Result,
190 },
191
192 /// Waiting for the Vulkan graphics queue to become idle failed.
193 #[error("failed to wait Vulkan queue idle: {result:?}")]
194 QueueWaitIdle {
195 /// Native Vulkan result code.
196 result: ash::vk::Result,
197 },
198
199 /// Creating a Vulkan-backed OpenXR session failed.
200 #[error("failed to create OpenXR Vulkan session: {result:?}")]
201 CreateSession {
202 /// Native OpenXR result code.
203 result: xr::sys::Result,
204 },
205
206 /// Creating the viewer reference space failed.
207 #[error("failed to create OpenXR view space: {result:?}")]
208 CreateViewSpace {
209 /// Native OpenXR result code.
210 result: xr::sys::Result,
211 },
212
213 /// Locating the viewer reference space failed.
214 #[error("failed to locate OpenXR view space: {result:?}")]
215 LocateViewSpace {
216 /// Native OpenXR result code.
217 result: xr::sys::Result,
218 },
219
220 /// Neither preferred nor fallback application reference space could be created.
221 #[error(
222 "failed to create OpenXR reference space for {preference}; local={local_error:?}, stage={stage_error:?}"
223 )]
224 CreateReferenceSpace {
225 /// Human-readable requested preference.
226 preference: &'static str,
227 /// Failure from the local-space attempt, if attempted.
228 local_error: Option<xr::sys::Result>,
229 /// Failure from the stage-space attempt, if attempted.
230 stage_error: Option<xr::sys::Result>,
231 },
232
233 /// Polling the instance event queue failed.
234 #[error("failed to poll OpenXR event: {result:?}")]
235 PollEvent {
236 /// Native OpenXR result code.
237 result: xr::sys::Result,
238 },
239
240 /// Beginning the OpenXR session failed.
241 #[error("failed to begin OpenXR session: {result:?}")]
242 BeginSession {
243 /// Native OpenXR result code.
244 result: xr::sys::Result,
245 },
246
247 /// Ending the OpenXR session failed.
248 #[error("failed to end OpenXR session: {result:?}")]
249 EndSession {
250 /// Native OpenXR result code.
251 result: xr::sys::Result,
252 },
253
254 /// Waiting for the next predicted display time failed.
255 #[error("failed to wait OpenXR frame: {result:?}")]
256 FrameWait {
257 /// Native OpenXR result code.
258 result: xr::sys::Result,
259 },
260
261 /// Beginning the frame stream failed.
262 #[error("failed to begin OpenXR frame stream: {result:?}")]
263 FrameBegin {
264 /// Native OpenXR result code.
265 result: xr::sys::Result,
266 },
267
268 /// Ending the frame stream or submitting layers failed.
269 #[error("failed to end OpenXR frame stream: {result:?}")]
270 FrameEnd {
271 /// Native OpenXR result code.
272 result: xr::sys::Result,
273 },
274
275 /// Creating an OpenXR action set failed.
276 #[error("failed to create OpenXR action set {name}: {result:?}")]
277 CreateActionSet {
278 /// Stable action-set name.
279 name: &'static str,
280 /// Native OpenXR result code.
281 result: xr::sys::Result,
282 },
283
284 /// Converting an OpenXR path string failed.
285 #[error("failed to resolve OpenXR path {path}: {result:?}")]
286 StringToPath {
287 /// Path string requested by the input binding.
288 path: &'static str,
289 /// Native OpenXR result code.
290 result: xr::sys::Result,
291 },
292
293 /// Creating an input action failed.
294 #[error("failed to create OpenXR action {name}: {result:?}")]
295 CreateAction {
296 /// Stable action name.
297 name: &'static str,
298 /// Native OpenXR result code.
299 result: xr::sys::Result,
300 },
301
302 /// A runtime rejected suggested bindings for an interaction profile.
303 #[error("failed to suggest OpenXR bindings for {profile}: {result:?}")]
304 SuggestInteractionProfileBindings {
305 /// OpenXR interaction-profile path.
306 profile: &'static str,
307 /// Native OpenXR result code.
308 result: xr::sys::Result,
309 },
310
311 /// Every supported interaction-profile binding suggestion was rejected.
312 #[error("no OpenXR interaction profile accepted Ailloli UI input bindings")]
313 NoInteractionProfileBindings,
314
315 /// Attaching the input action set to the session failed.
316 #[error("failed to attach OpenXR action sets: {result:?}")]
317 AttachActionSets {
318 /// Native OpenXR result code.
319 result: xr::sys::Result,
320 },
321
322 /// Creating a pose action space for one source failed.
323 #[error("failed to create OpenXR action space for {source_name}: {result:?}")]
324 CreateActionSpace {
325 /// Human-readable controller or hand source.
326 source_name: &'static str,
327 /// Native OpenXR result code.
328 result: xr::sys::Result,
329 },
330
331 /// Synchronizing action state for the current frame failed.
332 #[error("failed to sync OpenXR actions: {result:?}")]
333 SyncActions {
334 /// Native OpenXR result code.
335 result: xr::sys::Result,
336 },
337
338 /// Reading one action state failed.
339 #[error("failed to read OpenXR action state {action} for {source_name}: {result:?}")]
340 ActionState {
341 /// Action being read.
342 action: &'static str,
343 /// Controller or hand source being polled.
344 source_name: &'static str,
345 /// Native OpenXR result code.
346 result: xr::sys::Result,
347 },
348
349 /// Locating a pose action space failed.
350 #[error("failed to locate OpenXR action space for {source_name}: {result:?}")]
351 LocateActionSpace {
352 /// Controller or hand source being located.
353 source_name: &'static str,
354 /// Native OpenXR result code.
355 result: xr::sys::Result,
356 },
357
358 /// Creating an extension hand tracker failed.
359 #[error("failed to create OpenXR hand tracker for {source_name}: {result:?}")]
360 CreateHandTracker {
361 /// Left or right hand label.
362 source_name: &'static str,
363 /// Native OpenXR result code.
364 result: xr::sys::Result,
365 },
366
367 /// Locating hand joints for one frame failed.
368 #[error("failed to locate OpenXR hand joints for {source_name}: {result:?}")]
369 LocateHandJoints {
370 /// Left or right hand label.
371 source_name: &'static str,
372 /// Native OpenXR result code.
373 result: xr::sys::Result,
374 },
375
376 /// Swapchain width or height was zero.
377 #[error("invalid OpenXR swapchain extent {width}x{height}")]
378 InvalidSwapchainExtent {
379 /// Requested width in pixels.
380 width: u32,
381 /// Requested height in pixels.
382 height: u32,
383 },
384
385 /// Runtime swapchain-format enumeration failed.
386 #[error("failed to enumerate OpenXR swapchain formats: {result:?}")]
387 EnumerateSwapchainFormats {
388 /// Native OpenXR result code.
389 result: xr::sys::Result,
390 },
391
392 /// None of the runtime formats matched the renderer's Vulkan formats.
393 #[error("no compatible OpenXR Vulkan swapchain format; supported raw formats: {supported:?}")]
394 UnsupportedSwapchainFormat {
395 /// Raw Vulkan format values advertised by the runtime.
396 supported: Vec<u32>,
397 },
398
399 /// Creating an OpenXR swapchain failed.
400 #[error("failed to create OpenXR swapchain with {usage} usage: {result:?}")]
401 CreateSwapchain {
402 /// Human-readable attempted usage flags.
403 usage: &'static str,
404 /// Native OpenXR result code.
405 result: xr::sys::Result,
406 },
407
408 /// Enumerating native Vulkan images for a swapchain failed.
409 #[error("failed to enumerate OpenXR swapchain images: {result:?}")]
410 EnumerateSwapchainImages {
411 /// Native OpenXR result code.
412 result: xr::sys::Result,
413 },
414
415 /// Creating a Vulkan view for a swapchain image failed.
416 #[error("failed to create OpenXR swapchain image view: {result:?}")]
417 CreateSwapchainImageView {
418 /// Native Vulkan result code.
419 result: ash::vk::Result,
420 },
421
422 /// A staging operation required unavailable Vulkan memory properties.
423 #[error("missing Vulkan memory properties for {usage}")]
424 MissingVulkanMemoryProperties {
425 /// Staging operation requiring the properties.
426 usage: &'static str,
427 },
428
429 /// Creating a Vulkan staging buffer failed.
430 #[error("failed to create Vulkan staging buffer for {usage}: {result:?}")]
431 CreateStagingBuffer {
432 /// Staging-buffer purpose.
433 usage: &'static str,
434 /// Native Vulkan result code.
435 result: ash::vk::Result,
436 },
437
438 /// No memory type was both host-visible and coherent.
439 #[error("no host-visible coherent Vulkan memory type for {usage}")]
440 NoHostVisibleMemoryType {
441 /// Staging-buffer purpose.
442 usage: &'static str,
443 },
444
445 /// Vulkan staging-memory allocation failed.
446 #[error("failed to allocate Vulkan staging memory for {usage}: {result:?}")]
447 AllocateStagingMemory {
448 /// Staging-buffer purpose.
449 usage: &'static str,
450 /// Native Vulkan result code.
451 result: ash::vk::Result,
452 },
453
454 /// Binding staging memory to its Vulkan buffer failed.
455 #[error("failed to bind Vulkan staging memory for {usage}: {result:?}")]
456 BindStagingMemory {
457 /// Staging-buffer purpose.
458 usage: &'static str,
459 /// Native Vulkan result code.
460 result: ash::vk::Result,
461 },
462
463 /// Mapping staging memory into host address space failed.
464 #[error("failed to map Vulkan staging memory for {usage}: {result:?}")]
465 MapStagingMemory {
466 /// Staging-buffer purpose.
467 usage: &'static str,
468 /// Native Vulkan result code.
469 result: ash::vk::Result,
470 },
471
472 /// Runtime returned an image index beyond the enumerated image vector.
473 #[error("OpenXR swapchain image index {index} is out of bounds for {len} images")]
474 SwapchainImageIndexOutOfBounds {
475 /// Runtime-provided image index.
476 index: u32,
477 /// Number of known swapchain images.
478 len: usize,
479 },
480
481 /// Acquiring the next swapchain image failed.
482 #[error("failed to acquire OpenXR swapchain image: {result:?}")]
483 AcquireSwapchainImage {
484 /// Native OpenXR result code.
485 result: xr::sys::Result,
486 },
487
488 /// Waiting for an acquired swapchain image failed or timed out.
489 #[error("failed to wait OpenXR swapchain image: {result:?}")]
490 WaitSwapchainImage {
491 /// Native OpenXR result code.
492 result: xr::sys::Result,
493 },
494
495 /// Releasing an acquired swapchain image failed.
496 #[error("failed to release OpenXR swapchain image: {result:?}")]
497 ReleaseSwapchainImage {
498 /// Native OpenXR result code.
499 result: xr::sys::Result,
500 },
501
502 /// Ailloli's Vulkan renderer rejected setup or frame work.
503 #[error("ailloli_ui_render_vulkan failed: {source}")]
504 RenderVulkan {
505 /// Underlying renderer failure.
506 source: ailloli_ui_render_vulkan::VulkanRendererError,
507 },
508}