diff --git a/ash-window/src/lib.rs b/ash-window/src/lib.rs index 4d4cc99..885c48f 100644 --- a/ash-window/src/lib.rs +++ b/ash-window/src/lib.rs @@ -16,15 +16,22 @@ use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; /// /// # Safety /// -/// In order for the created [`vk::SurfaceKHR`] to be valid for the duration of its -/// usage, the [`Instance`] this was called on must be dropped later than the -/// resulting [`vk::SurfaceKHR`]. +/// There is a [parent/child relation] between [`Instance`] and [`Entry`], and the resulting +/// [`vk::SurfaceKHR`]. The application must not [destroy][Instance::destroy_instance()] these +/// parent objects before first [destroying][khr::Surface::destroy_surface()] the returned +/// [`vk::SurfaceKHR`] child object. [`vk::SurfaceKHR`] does _not_ implement [drop][drop()] +/// semantics and can only be destroyed via [`destroy_surface()`][khr::Surface::destroy_surface()]. +/// +/// See the [`Entry::create_instance()`] documentation for more destruction ordering rules on +/// [`Instance`]. /// /// The window represented by `window_handle` must be associated with the display connection /// in `display_handle`. /// /// `window_handle` and `display_handle` must be associated with a valid window and display /// connection, which must not be destroyed for the lifetime of the returned [`vk::SurfaceKHR`]. +/// +/// [parent/child relation]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#fundamentals-objectmodel-lifetime pub unsafe fn create_surface( entry: &Entry, instance: &Instance, diff --git a/ash/src/entry.rs b/ash/src/entry.rs index 695d7b2..fc9267f 100644 --- a/ash/src/entry.rs +++ b/ash/src/entry.rs @@ -34,9 +34,15 @@ impl Entry { /// development packages installed (e.g. the Vulkan SDK, or Ubuntu's `libvulkan-dev`). /// /// # Safety + /// /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines /// for [`Library::new()`] and [`Library::get()`] apply here. /// + /// No Vulkan functions loaded directly or indirectly from this [`Entry`] + /// may be called after it is [dropped][drop()]. + /// + /// # Example + /// /// ```no_run /// use ash::{vk, Entry}; /// # fn main() -> Result<(), Box> { @@ -83,6 +89,11 @@ impl Entry { /// Note that instance/device functions are still fetched via `vkGetInstanceProcAddr` and /// `vkGetDeviceProcAddr` for maximum performance. /// + /// Any Vulkan function acquired directly or indirectly from this [`Entry`] may be called after it + /// is [dropped][drop()]. + /// + /// # Example + /// /// ```no_run /// use ash::{vk, Entry}; /// # fn main() -> Result<(), Box> { @@ -113,8 +124,12 @@ impl Entry { /// Load Vulkan library at `path` /// /// # Safety + /// /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines /// for [`Library::new()`] and [`Library::get()`] apply here. + /// + /// No Vulkan functions loaded directly or indirectly from this [`Entry`] + /// may be called after it is [dropped][drop()]. #[cfg(feature = "loaded")] #[cfg_attr(docsrs, doc(cfg(feature = "loaded")))] pub unsafe fn load_from(path: impl AsRef) -> Result { @@ -137,8 +152,9 @@ impl Entry { /// Load entry points based on an already-loaded [`vk::StaticFn`] /// /// # Safety - /// `static_fn` must contain valid function pointers that comply with the semantics specified by - /// Vulkan 1.0, which must remain valid for at least the lifetime of the returned [`Entry`]. + /// + /// `static_fn` must contain valid function pointers that comply with the semantics specified + /// by Vulkan 1.0, which must remain valid for at least the lifetime of the returned [`Entry`]. pub unsafe fn from_static_fn(static_fn: vk::StaticFn) -> Self { let load_fn = move |name: &std::ffi::CStr| { mem::transmute((static_fn.get_instance_proc_addr)( @@ -180,6 +196,9 @@ impl Entry { } /// + /// + /// # Example + /// /// ```no_run /// # use ash::{Entry, vk}; /// # fn main() -> Result<(), Box> { @@ -216,9 +235,14 @@ impl Entry { /// /// /// # Safety - /// In order for the created [`Instance`] to be valid for the duration of its - /// usage, the [`Entry`][Self] this was called on must be dropped later than the - /// resulting [`Instance`]. + /// + /// The resulting [`Instance`] and any function-pointer objects (e.g. [`Device`][crate::Device] + /// and [extensions][crate::extensions]) loaded from it may not be used after this [`Entry`] + /// object is dropped, unless it was crated using [`Entry::linked()`] or + /// [`Entry::from_parts_1_1()`]. + /// + /// [`Instance`] does _not_ implement [drop][drop()] semantics and can only be destroyed via + /// [`destroy_instance()`][Instance::destroy_instance()]. #[inline] pub unsafe fn create_instance( &self, diff --git a/ash/src/instance.rs b/ash/src/instance.rs index 70db597..3893fae 100644 --- a/ash/src/instance.rs +++ b/ash/src/instance.rs @@ -1,3 +1,5 @@ +#[cfg(doc)] +use super::Entry; use crate::device::Device; use crate::prelude::*; use crate::vk; @@ -336,9 +338,17 @@ impl Instance { /// /// /// # Safety - /// In order for the created [`Device`] to be valid for the duration of its - /// usage, the [`Instance`] this was called on must be dropped later than the - /// resulting [`Device`]. + /// + /// There is a [parent/child relation] between [`Instance`] and the resulting [`Device`]. The + /// application must not [destroy][Instance::destroy_instance()] the parent [`Instance`] object + /// before first [destroying][Device::destroy_device()] the returned [`Device`] child object. + /// [`Device`] does _not_ implement [drop][drop()] semantics and can only be destroyed via + /// [`destroy_device()`][Device::destroy_device()]. + /// + /// See the [`Entry::create_instance()`] documentation for more destruction ordering rules on + /// [`Instance`]. + /// + /// [parent/child relation]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#fundamentals-objectmodel-lifetime #[inline] pub unsafe fn create_device( &self, diff --git a/ash/src/prelude.rs b/ash/src/prelude.rs index f752a6a..e434803 100644 --- a/ash/src/prelude.rs +++ b/ash/src/prelude.rs @@ -26,13 +26,12 @@ impl vk::Result { } } -/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, -/// ensuring all available data has been read into the vector. +/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, ensuring all +/// available data has been read into the vector. /// -/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available -/// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count -/// increased (and the vector is not large enough after querying the initial size), -/// requiring Ash to try again. +/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available items may +/// change between calls; [`vk::Result::INCOMPLETE`] is returned when the count increased (and the +/// vector is not large enough after querying the initial size), requiring Ash to try again. /// /// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html pub(crate) unsafe fn read_into_uninitialized_vector, T>( @@ -56,18 +55,17 @@ where } } -/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, -/// ensuring all available data has been read into the vector. +/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, ensuring all +/// available data has been read into the vector. /// -/// Items in the target vector are [`default()`][`Default::default()`]-initialized which -/// is required for [`vk::BaseOutStructure`]-like structs where [`vk::BaseOutStructure::s_type`] -/// needs to be a valid type and [`vk::BaseOutStructure::p_next`] a valid or -/// [`null`][`std::ptr::null_mut()`] pointer. +/// Items in the target vector are [`default()`][Default::default()]-initialized which is required +/// for [`vk::BaseOutStructure`]-like structs where [`vk::BaseOutStructure::s_type`] needs to be a +/// valid type and [`vk::BaseOutStructure::p_next`] a valid or [`null`][std::ptr::null_mut()] +/// pointer. /// -/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available -/// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count -/// increased (and the vector is not large enough after querying the initial size), -/// requiring Ash to try again. +/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available items may +/// change between calls; [`vk::Result::INCOMPLETE`] is returned when the count increased (and the +/// vector is not large enough after querying the initial size), requiring Ash to try again. /// /// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html pub(crate) unsafe fn read_into_defaulted_vector<