Remove "drop" mention from create_* docs when the result doesn't implement Drop (#625)

Ash doesn't implement `Drop` intentionally, to not be too opinionated
about holding (heap) references to their parent objects
(`Device`->`Instance`->`Entry`) and ensuring they are destroyed in the
right order.  As such, reword the `create` documentation for `Instance`
and `Device` to mention their respective `destroy_*` function instead of
referring to them as being "droppable".

Note that `Entry` is droppable as it does not have a Vulkan `destroy`
function _and_ the dynamically loaded library (behind the "loaded"
feature) is kept alive only for the lifetime of `Entry`.
This commit is contained in:
Marijn Suijten 2023-05-29 20:40:08 +02:00 committed by GitHub
parent 5287371195
commit 1e7ee6762f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 27 deletions

View file

@ -16,15 +16,22 @@ use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
/// ///
/// # Safety /// # Safety
/// ///
/// In order for the created [`vk::SurfaceKHR`] to be valid for the duration of its /// There is a [parent/child relation] between [`Instance`] and [`Entry`], and the resulting
/// usage, the [`Instance`] this was called on must be dropped later than the /// [`vk::SurfaceKHR`]. The application must not [destroy][Instance::destroy_instance()] these
/// resulting [`vk::SurfaceKHR`]. /// 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 /// The window represented by `window_handle` must be associated with the display connection
/// in `display_handle`. /// in `display_handle`.
/// ///
/// `window_handle` and `display_handle` must be associated with a valid window and display /// `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`]. /// 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( pub unsafe fn create_surface(
entry: &Entry, entry: &Entry,
instance: &Instance, instance: &Instance,

View file

@ -34,9 +34,15 @@ impl Entry {
/// development packages installed (e.g. the Vulkan SDK, or Ubuntu's `libvulkan-dev`). /// development packages installed (e.g. the Vulkan SDK, or Ubuntu's `libvulkan-dev`).
/// ///
/// # Safety /// # Safety
///
/// `dlopen`ing native libraries is inherently unsafe. The safety guidelines /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines
/// for [`Library::new()`] and [`Library::get()`] apply here. /// 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 /// ```no_run
/// use ash::{vk, Entry}; /// use ash::{vk, Entry};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> { /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -83,6 +89,11 @@ impl Entry {
/// Note that instance/device functions are still fetched via `vkGetInstanceProcAddr` and /// Note that instance/device functions are still fetched via `vkGetInstanceProcAddr` and
/// `vkGetDeviceProcAddr` for maximum performance. /// `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 /// ```no_run
/// use ash::{vk, Entry}; /// use ash::{vk, Entry};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> { /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -113,8 +124,12 @@ impl Entry {
/// Load Vulkan library at `path` /// Load Vulkan library at `path`
/// ///
/// # Safety /// # Safety
///
/// `dlopen`ing native libraries is inherently unsafe. The safety guidelines /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines
/// for [`Library::new()`] and [`Library::get()`] apply here. /// 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(feature = "loaded")]
#[cfg_attr(docsrs, doc(cfg(feature = "loaded")))] #[cfg_attr(docsrs, doc(cfg(feature = "loaded")))]
pub unsafe fn load_from(path: impl AsRef<OsStr>) -> Result<Self, LoadingError> { pub unsafe fn load_from(path: impl AsRef<OsStr>) -> Result<Self, LoadingError> {
@ -137,8 +152,9 @@ impl Entry {
/// Load entry points based on an already-loaded [`vk::StaticFn`] /// Load entry points based on an already-loaded [`vk::StaticFn`]
/// ///
/// # Safety /// # 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 { pub unsafe fn from_static_fn(static_fn: vk::StaticFn) -> Self {
let load_fn = move |name: &std::ffi::CStr| { let load_fn = move |name: &std::ffi::CStr| {
mem::transmute((static_fn.get_instance_proc_addr)( mem::transmute((static_fn.get_instance_proc_addr)(
@ -180,6 +196,9 @@ impl Entry {
} }
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceVersion.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceVersion.html>
///
/// # Example
///
/// ```no_run /// ```no_run
/// # use ash::{Entry, vk}; /// # use ash::{Entry, vk};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> { /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -216,9 +235,14 @@ impl Entry {
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateInstance.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateInstance.html>
/// ///
/// # Safety /// # 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 /// The resulting [`Instance`] and any function-pointer objects (e.g. [`Device`][crate::Device]
/// resulting [`Instance`]. /// 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] #[inline]
pub unsafe fn create_instance( pub unsafe fn create_instance(
&self, &self,

View file

@ -1,3 +1,5 @@
#[cfg(doc)]
use super::Entry;
use crate::device::Device; use crate::device::Device;
use crate::prelude::*; use crate::prelude::*;
use crate::vk; use crate::vk;
@ -336,9 +338,17 @@ impl Instance {
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateDevice.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateDevice.html>
/// ///
/// # Safety /// # 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 /// There is a [parent/child relation] between [`Instance`] and the resulting [`Device`]. The
/// resulting [`Device`]. /// 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] #[inline]
pub unsafe fn create_device( pub unsafe fn create_device(
&self, &self,

View file

@ -26,13 +26,12 @@ impl vk::Result {
} }
} }
/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, /// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, ensuring all
/// ensuring all available data has been read into the vector. /// available data has been read into the vector.
/// ///
/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available /// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available items may
/// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count /// change between calls; [`vk::Result::INCOMPLETE`] is returned when the count increased (and the
/// increased (and the vector is not large enough after querying the initial size), /// vector is not large enough after querying the initial size), requiring Ash to try again.
/// requiring Ash to try again.
/// ///
/// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html /// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>( pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>(
@ -56,18 +55,17 @@ where
} }
} }
/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, /// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, ensuring all
/// ensuring all available data has been read into the vector. /// available data has been read into the vector.
/// ///
/// Items in the target vector are [`default()`][`Default::default()`]-initialized which /// Items in the target vector are [`default()`][Default::default()]-initialized which is required
/// is required for [`vk::BaseOutStructure`]-like structs where [`vk::BaseOutStructure::s_type`] /// for [`vk::BaseOutStructure`]-like structs where [`vk::BaseOutStructure::s_type`] needs to be a
/// needs to be a valid type and [`vk::BaseOutStructure::p_next`] a valid or /// valid type and [`vk::BaseOutStructure::p_next`] a valid or [`null`][std::ptr::null_mut()]
/// [`null`][`std::ptr::null_mut()`] pointer. /// pointer.
/// ///
/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available /// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available items may
/// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count /// change between calls; [`vk::Result::INCOMPLETE`] is returned when the count increased (and the
/// increased (and the vector is not large enough after querying the initial size), /// vector is not large enough after querying the initial size), requiring Ash to try again.
/// requiring Ash to try again.
/// ///
/// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html /// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
pub(crate) unsafe fn read_into_defaulted_vector< pub(crate) unsafe fn read_into_defaulted_vector<