bort_vk/
queue.rs

1use crate::{Device, DeviceError, DeviceOwned, Fence};
2use ash::{
3    prelude::VkResult,
4    vk::{self, Handle},
5};
6use std::sync::Arc;
7
8pub struct Queue {
9    handle: vk::Queue,
10    family_index: u32,
11    queue_index: u32,
12
13    // dependencies
14    device: Arc<Device>,
15}
16
17impl Queue {
18    /// Uses vkGetDeviceQueue
19    pub fn new(
20        device: Arc<Device>,
21        family_index: u32,
22        queue_index: u32,
23    ) -> Result<Self, QueueError> {
24        let handle = unsafe { device.inner().get_device_queue(family_index, queue_index) };
25        if handle == vk::Queue::null() {
26            return Err(QueueError::NoQueueHandle {
27                device_handle: device.inner().handle(),
28                family_index,
29                queue_index,
30            });
31        }
32
33        Ok(Self {
34            handle,
35            family_index,
36            queue_index,
37            device,
38        })
39    }
40
41    /// Uses vkGetDeviceQueue2
42    pub fn new_v2(device: Arc<Device>, queue_info: vk::DeviceQueueInfo2Builder) -> Self {
43        let handle = unsafe { device.inner().get_device_queue2(&queue_info) };
44
45        Self {
46            handle,
47            family_index: queue_info.queue_family_index,
48            queue_index: queue_info.queue_index,
49            device,
50        }
51    }
52
53    pub fn submit<'a>(
54        &self,
55        submit_infos: impl IntoIterator<Item = vk::SubmitInfoBuilder<'a>>,
56        fence: Option<&Fence>,
57    ) -> VkResult<()> {
58        let vk_submit_infos: Vec<vk::SubmitInfo> = submit_infos
59            .into_iter()
60            .map(|submit_info| submit_info.build())
61            .collect();
62        let fence_handle = fence.map(|f| f.handle());
63
64        unsafe {
65            self.device.inner().queue_submit(
66                self.handle,
67                &vk_submit_infos,
68                fence_handle.unwrap_or_default(),
69            )
70        }
71    }
72
73    pub fn wait_idle(&self) -> Result<(), DeviceError> {
74        self.device.queue_wait_idle(self)
75    }
76
77    // Getters
78
79    pub fn handle(&self) -> vk::Queue {
80        self.handle
81    }
82
83    pub fn family_index(&self) -> u32 {
84        self.family_index
85    }
86
87    pub fn queue_index(&self) -> u32 {
88        self.queue_index
89    }
90}
91
92impl DeviceOwned for Queue {
93    #[inline]
94    fn device(&self) -> &Arc<Device> {
95        &self.device
96    }
97
98    #[inline]
99    fn handle_raw(&self) -> u64 {
100        self.handle.as_raw()
101    }
102}
103
104// ~~ Errors ~~
105
106#[derive(Debug, Clone, Copy)]
107pub enum QueueError {
108    NoQueueHandle {
109        device_handle: vk::Device,
110        family_index: u32,
111        queue_index: u32,
112    },
113}
114
115impl std::fmt::Display for QueueError {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        match *self {
118            Self::NoQueueHandle {
119                device_handle,
120                family_index,
121                queue_index,
122            } => write!(
123                f,
124                "queue family {} and index {} not found in device {}",
125                family_index,
126                queue_index,
127                device_handle.as_raw()
128            ),
129        }
130    }
131}
132
133impl std::error::Error for QueueError {}