Files
a0_basic_app
a1_vehicle
a2_async_sim
ab_glyph
ab_glyph_rasterizer
adler
adler32
agents
aho_corasick
anyhow
approx
aquamarine
ash
atty
bitflags
bytemuck
byteorder
cache_padded
cfg_if
chrono
color_quant
crc32fast
crossbeam_channel
crossbeam_deque
crossbeam_epoch
crossbeam_utils
deflate
draw2d
either
flexi_logger
generic_array
gif
glfw
glfw_sys
glob
image
indoc
itertools
jpeg_decoder
lazy_static
libc
libloading
log
matrixmultiply
memchr
memoffset
miniz_oxide
nalgebra
base
geometry
linalg
third_party
num_complex
num_cpus
num_integer
num_iter
num_rational
num_traits
owned_ttf_parser
paste
png
proc_macro2
proc_macro_error
proc_macro_error_attr
quote
raw_window_handle
rawpointer
rayon
rayon_core
regex
regex_syntax
scoped_threadpool
scopeguard
semver
semver_parser
serde
serde_derive
simba
smawk
spin_sleep
syn
terminal_size
textwrap
thiserror
thiserror_impl
tiff
time
triple_buffer
ttf_parser
typenum
unicode_width
unicode_xid
unindent
vk_sys
weezl
yansi
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use anyhow::{Context, Result};
use ash::{version::DeviceV1_0, vk};

/// This structure holds resources for managing an owned command pool.
/// "Owned" means that the owner is responsible for destroying the contained
/// resources before this struct is dropped.
pub struct OwnedCommandPool {
    command_pool: vk::CommandPool,
}

impl OwnedCommandPool {
    /// Create the command buffer pool.
    ///
    /// The caller is responsible for destroying the pool.
    pub fn new(
        logical_device: &ash::Device,
        queue_family_index: u32,
    ) -> Result<Self> {
        let create_info = vk::CommandPoolCreateInfo {
            queue_family_index,
            flags: vk::CommandPoolCreateFlags::TRANSIENT,
            ..Default::default()
        };
        let command_pool = unsafe {
            logical_device
                .create_command_pool(&create_info, None)
                .context("unable to create the command pool")?
        };

        Ok(Self { command_pool })
    }

    /// The raw command pool handle.
    ///
    /// # Unsafe Because
    ///
    /// - The returned reference is still logically 'owned' by this struct and
    ///   must not be destroyed except via a call to [Self::destroy].
    pub unsafe fn raw(&self) -> &vk::CommandPool {
        &self.command_pool
    }

    /// Allocate a new command buffer.
    ///
    /// # Unsafe Because
    ///
    /// - the caller must eventually call [Self::reset] or else resources will
    ///   be leaked
    pub unsafe fn allocate_command_buffer(
        &self,
        logical_device: &ash::Device,
    ) -> Result<vk::CommandBuffer> {
        let create_info = vk::CommandBufferAllocateInfo {
            command_pool: self.command_pool,
            level: vk::CommandBufferLevel::PRIMARY,
            command_buffer_count: 1,
            ..Default::default()
        };
        let command_buffer = logical_device
            .allocate_command_buffers(&create_info)
            .context("unable to allocate command buffer")?;
        Ok(command_buffer[0])
    }

    /// Free a command buffer's resources to be used by the pool again.
    ///
    /// # Unsafe Because
    ///
    /// - the caller is responsible for ensuring that the command buffer is
    ///   not being used anymore
    /// - only command buffers created by previous calls to
    ///   [Self::allocate_command_buffer] on this instance can be passed to
    ///   this function
    pub unsafe fn free_command_buffer(
        &self,
        logical_device: &ash::Device,
        command_buffer: vk::CommandBuffer,
    ) {
        let buffers = [command_buffer];
        logical_device.free_command_buffers(self.command_pool, &buffers);
    }

    /// Reset all command buffers allocated by this pool.
    ///
    /// # Unsafe Because
    ///
    /// - the caller is responsible for ensuring that none of the command
    ///   buffers are still in use
    pub unsafe fn reset(&self, logical_device: &ash::Device) -> Result<()> {
        logical_device
            .reset_command_pool(
                self.command_pool,
                vk::CommandPoolResetFlags::empty(),
            )
            .with_context(|| "unable to reset the command pool!")
    }

    /// Destroy the command pool.
    ///
    /// # Unsafe Because
    ///
    /// - the caller must ensure that the command pool is not in use when it is
    ///   destroyed.
    pub unsafe fn destroy(&mut self, logical_device: &ash::Device) {
        logical_device.destroy_command_pool(self.command_pool, None);
    }
}