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
use {
    ash::vk,
    ccthw_ash_instance::{LogicalDevice, VulkanHandle},
};

/// A Vulkan device queue.
///
/// The raw Ash Queue handle can be acquired through the VulkanHandle trait.
#[derive(Debug, Clone)]
pub struct Queue {
    properties: vk::QueueFamilyProperties,
    family_index: u32,
    index: u32,
    queue: vk::Queue,
}

// Public API
// ----------

impl Queue {
    /// The queue family flags.
    pub fn family_flags(&self) -> vk::QueueFlags {
        self.properties.queue_flags
    }

    /// The queue family index for this queue.
    pub fn family_index(&self) -> u32 {
        self.family_index
    }

    /// The index of the queue _within_ the family. This is almost never needed
    /// by Vulkan APIs, but it can be useful to verify if two queues are the
    /// same.
    pub fn index(&self) -> u32 {
        self.index
    }
}

impl std::fmt::Display for Queue {
    fn fmt(&self, format: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        format.write_fmt(format_args!("{self:#?}"))
    }
}

impl VulkanHandle for Queue {
    type Handle = vk::Queue;

    unsafe fn raw(&self) -> &Self::Handle {
        &self.queue
    }
}

// Private API
// -----------

impl Queue {
    pub(super) fn new(
        logical_device: &LogicalDevice,
        family_index: usize,
        index: usize,
    ) -> Self {
        let queue = unsafe {
            logical_device
                .raw()
                .get_device_queue(family_index as u32, index as u32)
        };
        let properties = logical_device
            .physical_device()
            .queue_family_properties()[family_index];
        Self {
            properties,
            family_index: family_index as u32,
            index: index as u32,
            queue,
        }
    }
}