Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
marc0246 committed Aug 19, 2022
1 parent 419f428 commit c0f162a
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 68 deletions.
41 changes: 17 additions & 24 deletions vulkano/src/command_buffer/allocator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
//! A command pool holds and manages the memory of one or more command buffers. If you destroy a
//! command pool, all of its command buffers are automatically destroyed.
//!
//! In vulkano, creating a command buffer requires passing an implementation of the `CommandPool`
//! trait. By default vulkano will use the `StandardCommandPool` struct, but you can implement
//! this trait yourself by wrapping around the `UnsafeCommandPool` type.
//! In vulkano, creating a command buffer requires passing an implementation of the
//! [`CommandBufferAllocator`] trait, which you can implement yourself or use the vulkano-provided
//! [`StandardCommandBufferAllocator`].
pub use self::standard::StandardCommandBufferAllocator;
use super::{pool::CommandPoolAlloc, CommandBufferLevel};
Expand All @@ -30,33 +30,28 @@ pub mod standard;
/// # Safety
///
/// A Vulkan command pool must be externally synchronized as if it owned the command buffers that
/// were allocated from it. This includes allocating from the pool, freeing from the pool,
/// resetting the pool or individual command buffers, and most importantly recording commands to
/// command buffers.
///
/// The implementation of `CommandPool` is expected to manage this. For as long as a `Builder`
/// is alive, the trait implementation is expected to lock the pool that allocated the `Builder`
/// for the current thread.
///
/// > **Note**: This may be modified in the future to allow different implementation strategies.
///
/// The destructors of the `CommandPoolBuilderAlloc` and the `CommandPoolAlloc` are expected to
/// free the command buffer, reset the command buffer, or add it to a pool so that it gets reused.
/// If the implementation frees or resets the command buffer, it must not forget that this
/// operation must lock the pool.
/// were allocated from it. This includes allocating from the pool, freeing from the pool, resetting
/// the pool or individual command buffers, and most importantly recording commands to command
/// buffers. The implementation of `CommandBufferAllocator` is expected to manage this.
///
/// The destructors of the [`CommandBufferBuilderAlloc`] and the [`CommandBufferAlloc`] are expected
/// to free the command buffer, reset the command buffer, or add it to a pool so that it gets
/// reused. If the implementation frees or resets the command buffer, it must not forget that this
/// operation must be externally synchronized.
pub unsafe trait CommandBufferAllocator: DeviceOwned {
/// See `alloc()`.
/// See [`allocate`](Self::allocate).
type Iter: Iterator<Item = Self::Builder>;

/// Represents a command buffer that has been allocated and that is currently being built.
type Builder: CommandBufferBuilderAlloc<Alloc = Self::Alloc>;

/// Represents a command buffer that has been allocated and that is pending execution or is
/// being executed.
type Alloc: CommandBufferAlloc;

/// Allocates command buffers from this pool.
/// Allocates command buffers.
///
/// Returns an iterator that contains an bunch of allocated command buffers.
/// Returns an iterator that contains the requested amount of allocated command buffers.
fn allocate(
&self,
level: CommandBufferLevel,
Expand All @@ -71,8 +66,7 @@ pub unsafe trait CommandBufferAllocator: DeviceOwned {
///
/// # Safety
///
/// See `CommandPool` for information about safety.
///
/// See [`CommandBufferAllocator`] for information about safety.
pub unsafe trait CommandBufferBuilderAlloc: DeviceOwned {
/// Return type of `into_alloc`.
type Alloc: CommandBufferAlloc;
Expand All @@ -91,8 +85,7 @@ pub unsafe trait CommandBufferBuilderAlloc: DeviceOwned {
///
/// # Safety
///
/// See `CommandPool` for information about safety.
///
/// See [`CommandBufferAllocator`] for information about safety.
pub unsafe trait CommandBufferAlloc: DeviceOwned + Send + Sync + 'static {
/// Returns the internal object that contains the command buffer.
fn inner(&self) -> &CommandPoolAlloc;
Expand Down
25 changes: 14 additions & 11 deletions vulkano/src/command_buffer/allocator/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ use crate::{
use crossbeam_queue::SegQueue;
use std::{marker::PhantomData, mem::ManuallyDrop, ptr, sync::Arc, vec::IntoIter as VecIntoIter};

/// Standard implementation of a command pool.
/// Standard implementation of a command buffer allocator.
///
/// A thread can have as many `Arc<StandardCommandPool>`s as needed, but none of them can escape the
/// thread they were created on. This is done so that there are no locks involved when creating
/// command buffers. Command buffers can't be moved between threads during the building process, but
/// finished command buffers can. When a command buffer is dropped, it is returned back to the pool
/// for reuse.
/// A thread can have as many `Arc<StandardCommandBufferAllocator>`s as needed, but they can't be
/// shared between threads. This is done so that there are no locks involved when creating command
/// buffers. You are encouraged to create one allocator per frame in flight per thread.
///
/// Command buffers can't be moved between threads during the building process, but finished command
/// buffers can. When a command buffer is dropped, it is returned back to the pool for reuse.
#[derive(Debug)]
pub struct StandardCommandBufferAllocator {
// The Vulkan pool specific to a device's queue family.
Expand All @@ -41,7 +42,7 @@ pub struct StandardCommandBufferAllocator {
}

impl StandardCommandBufferAllocator {
/// Builds a new pool.
/// Builds a new allocator.
///
/// # Panics
///
Expand Down Expand Up @@ -150,10 +151,12 @@ unsafe impl DeviceOwned for StandardCommandBufferAllocator {
}
}

/// Command buffer allocated from a `StandardCommandPool` that is currently being built.
/// Command buffer allocated from a [`StandardCommandBufferAllocator`] that is currently being
/// built.
pub struct StandardCommandBufferBuilderAlloc {
// The only difference between a `StandardCommandPoolBuilder` and a `StandardCommandPoolAlloc`
// is that the former must not implement `Send` and `Sync`. Therefore we just share the structs.
// The only difference between a `StandardCommandBufferBuilder` and a
// `StandardCommandBufferAlloc` is that the former must not implement `Send` and `Sync`.
// Therefore we just share the structs.
inner: StandardCommandBufferAlloc,
// Unimplemented `Send` and `Sync` from the builder.
dummy_avoid_send_sync: PhantomData<*const u8>,
Expand Down Expand Up @@ -185,7 +188,7 @@ unsafe impl DeviceOwned for StandardCommandBufferBuilderAlloc {
}
}

/// Command buffer allocated from a `StandardCommandPool`.
/// Command buffer allocated from a [`StandardCommandBufferAllocator`].
pub struct StandardCommandBufferAlloc {
// The actual command buffer. Extracted in the `Drop` implementation.
cmd: ManuallyDrop<CommandPoolAlloc>,
Expand Down
8 changes: 4 additions & 4 deletions vulkano/src/command_buffer/auto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ use std::{
},
};

/// Note that command buffers allocated from the default command pool (`Arc<StandardCommandPool>`)
/// don't implement the `Send` and `Sync` traits. If you use this pool, then the
/// `AutoCommandBufferBuilder` will not implement `Send` and `Sync` either. Once a command buffer
/// is built, however, it *does* implement `Send` and `Sync`.
/// Note that command buffers allocated from `Arc<StandardCommandBufferAllocator>` don't implement
/// the `Send` and `Sync` traits. If you use this allocator, then the `AutoCommandBufferBuilder`
/// will not implement `Send` and `Sync` either. Once a command buffer is built, however, it *does*
/// implement `Send` and `Sync`.
pub struct AutoCommandBufferBuilder<L, A = Arc<StandardCommandBufferAllocator>>
where
A: CommandBufferAllocator,
Expand Down
18 changes: 10 additions & 8 deletions vulkano/src/command_buffer/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::{
sync::Arc,
};

/// Low-level implementation of a command pool.
/// Represents a Vulkan command pool.
///
/// A command pool is always tied to a specific queue family. Command buffers allocated from a pool
/// can only be executed on the corresponding queue family.
Expand All @@ -34,7 +34,7 @@ use std::{
pub struct CommandPool {
handle: ash::vk::CommandPool,
device: Arc<Device>,
// We don't want `UnsafeCommandPool` to implement Sync.
// We don't want `CommandPool` to implement Sync.
// This marker unimplements both Send and Sync, but we reimplement Send manually right under.
dummy_avoid_sync: PhantomData<*const u8>,

Expand All @@ -46,7 +46,7 @@ pub struct CommandPool {
unsafe impl Send for CommandPool {}

impl CommandPool {
/// Creates a new `UnsafeCommandPool`.
/// Creates a new `CommandPool`.
pub fn new(
device: Arc<Device>,
mut create_info: CommandPoolCreateInfo,
Expand All @@ -72,10 +72,12 @@ impl CommandPool {
})
}

/// Creates a new `UnsafeCommandPool` from an ash-handle
/// Creates a new `CommandPool` from an ash-handle.
///
/// # Safety
/// The `handle` has to be a valid vulkan object handle and
/// the `create_info` must match the info used to create said object
///
/// - The `handle` has to be a valid vulkan object handle.
/// - The `create_info` must match the info used to create said object.
pub unsafe fn from_handle(
handle: ash::vk::CommandPool,
create_info: CommandPoolCreateInfo,
Expand Down Expand Up @@ -354,7 +356,7 @@ impl Hash for CommandPool {
}
}

/// Error that can happen when creating an `UnsafeCommandPool`.
/// Error that can happen when creating an `CommandPool`.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CommandPoolCreationError {
/// Not enough memory.
Expand Down Expand Up @@ -405,7 +407,7 @@ impl From<VulkanError> for CommandPoolCreationError {
}
}

/// Parameters to create an `UnsafeCommandPool`.
/// Parameters to create an `CommandPool`.
#[derive(Clone, Debug)]
pub struct CommandPoolCreateInfo {
/// The index of the queue family that this pool is created for. All command buffers allocated
Expand Down
23 changes: 21 additions & 2 deletions vulkano/src/descriptor_set/allocator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
// notice may not be copied, modified, or distributed except
// according to those terms.

//! A pool from which descriptor sets can be allocated.
//! In the Vulkan API, descriptor sets must be allocated from *descriptor pools*.
//!
//! A descriptor pool holds and manages the memory of one or more descriptor sets. If you destroy a
//! descriptor pool, all of its descriptor sets are automatically destroyed.
//!
//! In vulkano, creating a descriptor set requires passing an implementation of the
//! [`DescriptorSetAllocator`] trait, which you can implement yourself or use the vulkano-provided
//! [`StandardDescriptorSetAllocator`].
pub use self::standard::StandardDescriptorSetAllocator;
use super::{layout::DescriptorSetLayout, sys::UnsafeDescriptorSet};
Expand All @@ -16,7 +23,19 @@ use std::sync::Arc;

pub mod standard;

/// A pool from which descriptor sets can be allocated.
/// Types that manage the memory of descriptor sets.
///
/// # Safety
///
/// A Vulkan descriptor pool must be externally synchronized as if it owned the descriptor sets that
/// were allocated from it. This includes allocating from the pool, freeing from the pool and
/// resetting the pool or individual descriptor sets. The implementation of `DescriptorSetAllocator`
/// is expected to manage this.
///
/// The destructor of the [`DescriptorSetAlloc`] is expected to free the descriptor set, reset the
/// descriptor set, or add it to a pool so that it gets reused. If the implementation frees or
/// resets the descriptor set, it must not forget that this operation must be externally
/// synchronized.
pub unsafe trait DescriptorSetAllocator: DeviceOwned {
/// Object that represented an allocated descriptor set.
///
Expand Down
6 changes: 3 additions & 3 deletions vulkano/src/descriptor_set/allocator/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
};
use std::{collections::HashMap, sync::Arc};

/// Standard implementation of a descriptor pool.
/// Standard implementation of a descriptor set allocator.
///
/// Interally, this implementation uses one [`SingleLayoutDescSetPool`] /
/// [`SingleLayoutVariableDescSetPool`] per descriptor set layout.
Expand All @@ -39,7 +39,7 @@ enum Pool {
}

impl StandardDescriptorSetAllocator {
/// Builds a new `StandardDescriptorPool`.
/// Builds a new `StandardDescriptorSetAllocator`.
pub fn new(device: Arc<Device>) -> StandardDescriptorSetAllocator {
StandardDescriptorSetAllocator {
device,
Expand Down Expand Up @@ -104,7 +104,7 @@ unsafe impl DeviceOwned for StandardDescriptorSetAllocator {
}
}

/// A descriptor set allocated from a `StandardDescriptorPool`.
/// A descriptor set allocated from a [`StandardDescriptorSetAllocator`].
#[derive(Debug)]
pub struct StandardDescriptorSetAlloc {
// The actual descriptor alloc.
Expand Down
27 changes: 16 additions & 11 deletions vulkano/src/descriptor_set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,31 @@
//!
//! - A `DescriptorSetLayout` is a Vulkan object that describes to the Vulkan implementation the
//! layout of a future descriptor set. When you allocate a descriptor set, you have to pass an
//! instance of this object. This is represented with the `DescriptorSetLayout` type in
//! instance of this object. This is represented with the [`DescriptorSetLayout`] type in
//! vulkano.
//! - A `DescriptorPool` is a Vulkan object that holds the memory of descriptor sets and that can
//! be used to allocate and free individual descriptor sets. This is represented with the
//! `UnsafeDescriptorPool` type in vulkano.
//! [`DescriptorPool`] type in vulkano.
//! - A `DescriptorSet` contains the bindings to resources and is allocated from a pool. This is
//! represented with the `UnsafeDescriptorSet` type in vulkano.
//! represented with the [`UnsafeDescriptorSet`] type in vulkano.
//!
//! In addition to this, vulkano defines the following:
//!
//! - The `DescriptorPool` trait can be implemented on types from which you can allocate and free
//! descriptor sets. However it is different from Vulkan descriptor pools in the sense that an
//! implementation of the `DescriptorPool` trait can manage multiple Vulkan descriptor pools.
//! - The `StandardDescriptorPool` type is a default implementation of the `DescriptorPool` trait.
//! - The `DescriptorSet` trait is implemented on types that wrap around Vulkan descriptor sets in
//! - The [`DescriptorSetAllocator`] trait can be implemented on types from which you can allocate
//! and free descriptor sets. However it is different from Vulkan descriptor pools in the sense
//! that an implementation of the [`DescriptorSetAllocator`] trait can manage multiple Vulkan
//! descriptor pools.
//! - The [`StandardDescriptorSetAllocator`] type is a default implementation of the
//! [`DescriptorSetAllocator`] trait.
//! - The [`DescriptorSet`] trait is implemented on types that wrap around Vulkan descriptor sets in
//! a safe way. A Vulkan descriptor set is inherently unsafe, so we need safe wrappers around
//! them.
//! - The `SimpleDescriptorSet` type is a default implementation of the `DescriptorSet` trait.
//! - The `DescriptorSetsCollection` trait is implemented on collections of types that implement
//! `DescriptorSet`. It is what you pass to the draw functions.
//! - The [`DescriptorSetsCollection`] trait is implemented on collections of types that implement
//! [`DescriptorSet`]. It is what you pass to the draw functions.
//!
//! [`DescriptorPool`]: pool::DescriptorPool
//! [`DescriptorSetAllocator`]: allocator::DescriptorSetAllocator
//! [`StandardDescriptorSetAllocator`]: allocator::StandardDescriptorSetAllocator
pub(crate) use self::update::{check_descriptor_write, DescriptorWriteInfo};
pub use self::{
Expand Down
10 changes: 5 additions & 5 deletions vulkano/src/descriptor_set/single_layout_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ const MAX_POOLS: usize = 32;
/// `SingleLayoutDescSetPool` is a convenience wrapper provided by Vulkano not to be confused with
/// `VkDescriptorPool`. Its function is to provide access to pool(s) to allocate descriptor sets
/// from and optimizes for a specific layout which must not have a variable descriptor count. If
/// you need a variable descriptor count see [`SingleLayoutVariableDescSetPool`]. For a more general
/// purpose pool see [`StandardDescriptorPool`].
/// you need a variable descriptor count see [`SingleLayoutVariableDescSetPool`]. For a
/// general-purpose descriptor set allocator see [`StandardDescriptorSetAllocator`].
///
/// [`StandardDescriptorPool`]: super::pool::standard::StandardDescriptorPool
/// [`StandardDescriptorSetAllocator`]: super::allocator::standard::StandardDescriptorSetAllocator
#[derive(Debug)]
pub struct SingleLayoutDescSetPool {
// The `SingleLayoutPool` struct contains an actual Vulkan pool. Every time it is full we create
Expand Down Expand Up @@ -256,9 +256,9 @@ impl Hash for SingleLayoutDescSet {
/// Much like [`SingleLayoutDescSetPool`], except that it allows you to allocate descriptor sets
/// with a variable descriptor count. As this has more overhead, you should only use this pool if
/// you need the functionality and prefer [`SingleLayoutDescSetPool`] otherwise. For a more general
/// purpose pool see [`StandardDescriptorPool`].
/// purpose descriptor set allocator see [`StandardDescriptorSetAllocator`].
///
/// [`StandardDescriptorPool`]: super::pool::standard::StandardDescriptorPool
/// [`StandardDescriptorSetAllocator`]: super::allocator::standard::StandardDescriptorSetAllocator
#[derive(Debug)]
pub struct SingleLayoutVariableDescSetPool {
// The `SingleLayoutVariablePool` struct contains an actual Vulkan pool. Every time it is full
Expand Down

0 comments on commit c0f162a

Please sign in to comment.