vulkayes_core/queue/
mod.rs1use std::{
2 fmt::{Debug, Formatter},
3 ops::Deref
4};
5
6use ash::{
7 version::{DeviceV1_0, DeviceV1_1},
8 vk::{self, DeviceQueueCreateFlags, DeviceQueueInfo2}
9};
10
11use crate::{device::Device, prelude::Vrc, sync::fence::Fence, util::sync::Vutex};
12
13#[macro_use]
14pub mod macros;
15
16pub mod error;
17pub mod sharing_mode;
18
19pub struct Queue {
21 device: Vrc<Device>,
22 queue: Vutex<ash::vk::Queue>,
23
24 queue_family_index: u32,
26 queue_index: u32
27}
28impl Queue {
29 const_queue_submit! {
30 pub fn submit_one_fence_only(
31 &queue,
32 waits: [&Semaphore; 0],
33 stages: [vk::PipelineStageFlags; _],
34 buffers: [&CommandBuffer; 1],
35 signals: [&Semaphore; 0],
36 fence: Option<&Fence>
37 ) -> Result<(), QueueSubmitError>;
38 }
39
40 const_queue_submit! {
41 pub fn submit_one(
45 &queue,
46 waits: [&Semaphore; 1],
47 stages: [vk::PipelineStageFlags; _],
48 buffers: [&CommandBuffer; 1],
49 signals: [&Semaphore; 1],
50 fence: Option<&Fence>
51 ) -> Result<(), QueueSubmitError>;
52 }
53
54 const_queue_present! {
55 pub fn present_one(
59 &queue,
60 waits: [&Semaphore; 1],
61 images: [&SwapchainImage; 1],
62 result_for_all: bool
63 ) -> QueuePresentMultipleResult<[QueuePresentResult; _]>;
64 }
65
66 pub unsafe fn from_device(
73 device: Vrc<Device>,
74 flags: DeviceQueueCreateFlags,
75 queue_family_index: u32,
76 queue_index: u32
77 ) -> Vrc<Self> {
78 log_trace_common!(
79 "Creating queue:",
80 device,
81 flags,
82 queue_family_index,
83 queue_index
84 );
85 let queue = if flags.is_empty() {
86 device.get_device_queue(queue_family_index, queue_index)
87 } else {
88 let mut mem = std::mem::MaybeUninit::uninit();
89
90 let info = DeviceQueueInfo2::builder()
91 .flags(flags)
92 .queue_family_index(queue_family_index)
93 .queue_index(queue_index);
94 device
95 .fp_v1_1()
96 .get_device_queue2(device.handle(), info.deref(), mem.as_mut_ptr());
97
98 mem.assume_init()
99 };
100
101 Vrc::new(Queue {
102 device,
103 queue: Vutex::new(queue),
104 queue_family_index,
105 queue_index
106 })
107 }
108
109 pub unsafe fn submit(
119 &self,
120 infos: impl AsRef<[vk::SubmitInfo]>,
121 fence: Option<&Fence>
122 ) -> Result<(), error::QueueSubmitError> {
123 let lock = self.queue.lock().expect("vutex poisoned");
124
125 log_trace_common!(
126 "Submitting on queue:",
127 self,
128 crate::util::fmt::format_handle(*lock),
129 infos.as_ref(),
130 fence
131 );
132
133 if let Some(fence) = fence {
134 let fence_lock = fence.lock().expect("vutex poisoned");
135 self.device
136 .queue_submit(*lock, infos.as_ref(), *fence_lock)
137 .map_err(Into::into)
138 } else {
139 self.device
140 .queue_submit(*lock, infos.as_ref(), vk::Fence::null())
141 .map_err(Into::into)
142 }
143 }
144
145 pub fn wait(&self) -> Result<(), error::QueueWaitError> {
151 let lock = self.queue.lock().expect("vutex poisoned");
152
153 unsafe { self.device.queue_wait_idle(*lock).map_err(Into::into) }
154 }
155
156 pub const fn device(&self) -> &Vrc<Device> {
157 &self.device
158 }
159
160 pub const fn queue_family_index(&self) -> u32 {
161 self.queue_family_index
162 }
163
164 pub const fn queue_index(&self) -> u32 {
165 self.queue_index
166 }
167}
168impl_common_handle_traits! {
169 impl HasSynchronizedHandle<vk::Queue>, Deref, Borrow, Eq, Hash, Ord for Queue {
170 target = { queue }
171 }
172}
173impl Debug for Queue {
174 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
175 f.debug_struct("Queue")
176 .field("device", &self.device)
177 .field("queue", &self.queue)
178 .field("queue_family_index", &self.queue_family_index)
179 .field("queue_index", &self.queue_index)
180 .finish()
181 }
182}