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 device: Arc<Device>,
15}
16
17impl Queue {
18 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 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 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#[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 {}