dacite/vulkan_object.rs
1// Copyright (c) 2017, Dennis Hamester <dennis.hamester@startmail.com>
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13// PERFORMANCE OF THIS SOFTWARE.
14
15use std::error::Error;
16use std::fmt;
17
18use core;
19
20pub trait VulkanObject: Sized + Send + Sync + Clone + fmt::Debug {
21 type NativeVulkanObject;
22
23 /// Get the object id.
24 ///
25 /// This function returns the same value as `as_native_vulkan_object()`, but conveniently cast
26 /// to a `u64`. This is useful for extensions like `VK_EXT_debug_report` and
27 /// `VK_EXT_debug_marker`, which use these to refer Vulkan objects.
28 ///
29 /// Object ids (or more correctly, handles) come in two variants, *dispatchable* and
30 /// *non-dispatchable*. While dispatchable objects are actually pointers, and thus unique,
31 /// the same is not true for non-dispatchable objects. For instance, two `Semaphore`s, created
32 /// independently of each other, might in fact have the same handle.
33 ///
34 /// Additionally, handles of non-dispatchable objects are only ever meaningful, if their type
35 /// is known (whether it is i.e. a `Semaphore` or some other type). This must be taken into
36 /// account, if handles are used to identify Vulkan objects.
37 ///
38 /// Refer to the Vulkan specification ([Object Model]) for more information.
39 ///
40 /// [Object Model]:
41 /// https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#fundamentals-objectmodel-overview
42 fn id(&self) -> u64;
43
44 fn as_native_vulkan_object(&self) -> Self::NativeVulkanObject;
45 fn try_destroy(self) -> Result<(), TryDestroyError<Self>>;
46}
47
48pub struct TryDestroyError<T: VulkanObject> {
49 object: T,
50 kind: TryDestroyErrorKind,
51}
52
53impl<T: VulkanObject> fmt::Debug for TryDestroyError<T> {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 f.debug_struct("TryDestroyError")
56 .field("object", &"VulkanObject")
57 .field("kind", &self.kind)
58 .finish()
59 }
60}
61
62impl<T: VulkanObject> fmt::Display for TryDestroyError<T> {
63 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64 match self.kind {
65 TryDestroyErrorKind::InUse(Some(strong_count)) => write!(f, "This Vulkan object still has a reference counter of {} and can not be destroyed", strong_count),
66 _ => write!(f, "{}", self.description()),
67 }
68 }
69}
70
71impl<T: VulkanObject> Error for TryDestroyError<T> {
72 fn description(&self) -> &str {
73 match self.kind {
74 TryDestroyErrorKind::Unsupported => "This Vulkan object can not be destroyed explicitly",
75 TryDestroyErrorKind::InUse(_) => "This Vulkan object is referenced elsewhere",
76 TryDestroyErrorKind::VulkanError(_) => "A Vulkan error occurred while trying to destroy the object",
77 }
78 }
79}
80
81impl<T: VulkanObject> TryDestroyError<T> {
82 pub fn new(object: T, kind: TryDestroyErrorKind) -> Self {
83 TryDestroyError {
84 object: object,
85 kind: kind,
86 }
87 }
88
89 /// Consumes this error and returns the Vulkan object in its original state.
90 pub fn into_vulkan_object(self) -> T {
91 self.object
92 }
93
94 pub fn kind(&self) -> TryDestroyErrorKind {
95 self.kind
96 }
97}
98
99/// Indicates the kind of error, which occurred while trying to delete a Vulkan object.
100#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
101pub enum TryDestroyErrorKind {
102 /// The Vulkan object can not be destroyed explicitly.
103 ///
104 /// This is the case for objects, which are implicitly destroyed with its parent
105 /// (e.g. PhysicalDevice and Queue).
106 Unsupported,
107
108 /// The Vulkan object is still in use.
109 ///
110 /// The optional usize value indicates the current reference counter.
111 InUse(Option<usize>),
112
113 /// A Vulkan error occurred at runtime.
114 VulkanError(core::Error),
115}
116
117/// Trait for creating dacite Vulkan objects from native FFI objects.
118///
119/// This trait is provided for interoperability with other Vulkan-related libraries, if you need to
120/// create dacite Vulkan objects from existing native FFI objects.
121///
122/// Not all dacite Vulkan objects implement this trait, which is why this is a separate trait
123/// instead of being integrated in the `VulkanObject` trait.
124///
125/// __Caution__: Many implementors can optionally own the underlying native object (specified
126/// through an `owned` parameter). This means, that the Vulkan object will be destroyed, when this
127/// object is dropped. You must not create multiple dacite objects, which own the same Vulkan
128/// object.
129pub trait FromNativeObject: VulkanObject {
130 type Parameters;
131
132 unsafe fn from_native_object(object: Self::NativeVulkanObject, params: Self::Parameters) -> Self;
133}