rendy_command/family/
queue.rs1use {
2 super::{submission::*, QueueId},
3 crate::{buffer::Submittable, fence::*},
4 rendy_core::hal::{queue::CommandQueue, Backend},
5};
6
7#[derive(Debug)]
9pub struct Queue<B: Backend> {
10 raw: B::CommandQueue,
11 id: QueueId,
12 next_epoch: u64,
13}
14
15family_owned!(@NOCAP Queue<B> @ |q: &Self| q.id.family);
16
17impl<B> Queue<B>
18where
19 B: Backend,
20{
21 pub(super) fn new(raw: B::CommandQueue, id: QueueId) -> Self {
22 Queue {
23 id,
24 raw,
25 next_epoch: 0,
26 }
27 }
28
29 pub fn id(&self) -> QueueId {
31 self.id
32 }
33
34 pub fn raw(&mut self) -> &mut impl CommandQueue<B> {
36 &mut self.raw
37 }
38
39 pub fn next_epoch(&self) -> u64 {
41 self.next_epoch
42 }
43
44 pub unsafe fn submit<'a>(
47 &mut self,
48 submissions: impl IntoIterator<
49 Item = Submission<
50 B,
51 impl IntoIterator<
52 Item = (
53 &'a (impl std::borrow::Borrow<B::Semaphore> + 'a),
54 rendy_core::hal::pso::PipelineStage,
55 ),
56 >,
57 impl IntoIterator<Item = impl Submittable<B>>,
58 impl IntoIterator<Item = &'a (impl std::borrow::Borrow<B::Semaphore> + 'a)>,
59 >,
60 >,
61 fence: Option<&mut Fence<B>>,
62 ) {
63 assert!(fence.as_ref().map_or(true, |f| f.is_unsignaled()));
64
65 let mut submissions = submissions.into_iter().peekable();
66 if submissions.peek().is_none() && fence.is_some() {
67 self.raw.submit(
68 rendy_core::hal::queue::Submission {
69 command_buffers: std::iter::empty::<&'a B::CommandBuffer>(),
70 wait_semaphores: std::iter::empty::<(&'a B::Semaphore, _)>(),
71 signal_semaphores: std::iter::empty::<&'a B::Semaphore>(),
72 },
73 fence.as_ref().map(|f| f.raw()),
74 );
75 } else {
76 let family = self.id.family;
77 while let Some(submission) = submissions.next() {
78 self.raw.submit(
79 rendy_core::hal::queue::Submission {
80 command_buffers: submission.submits.into_iter().map(|submit| {
81 assert_eq!(submit.family(), family);
82 submit.raw()
83 }),
84 wait_semaphores: submission.waits.into_iter().map(|w| (w.0.borrow(), w.1)),
85 signal_semaphores: submission.signals.into_iter().map(|s| s.borrow()),
86 },
87 submissions
88 .peek()
89 .map_or(fence.as_ref().map(|f| f.raw()), |_| None),
90 );
91 }
92 }
93
94 if let Some(fence) = fence {
95 fence.mark_submitted(FenceEpoch {
96 queue: self.id,
97 epoch: self.next_epoch,
98 });
99 self.next_epoch += 1;
100 }
101 }
102
103 pub unsafe fn submit_raw_fence<'a>(
107 &mut self,
108 submissions: impl IntoIterator<
109 Item = Submission<
110 B,
111 impl IntoIterator<
112 Item = (
113 &'a (impl std::borrow::Borrow<B::Semaphore> + 'a),
114 rendy_core::hal::pso::PipelineStage,
115 ),
116 >,
117 impl IntoIterator<Item = impl Submittable<B>>,
118 impl IntoIterator<Item = &'a (impl std::borrow::Borrow<B::Semaphore> + 'a)>,
119 >,
120 >,
121 fence: Option<&B::Fence>,
122 ) {
123 let mut submissions = submissions.into_iter().peekable();
124 if submissions.peek().is_none() && fence.is_some() {
125 self.raw.submit(
126 rendy_core::hal::queue::Submission {
127 command_buffers: std::iter::empty::<&'a B::CommandBuffer>(),
128 wait_semaphores: std::iter::empty::<(&'a B::Semaphore, _)>(),
129 signal_semaphores: std::iter::empty::<&'a B::Semaphore>(),
130 },
131 fence,
132 );
133 } else {
134 let family = self.id.family;
135 while let Some(submission) = submissions.next() {
136 self.raw.submit(
137 rendy_core::hal::queue::Submission {
138 command_buffers: submission.submits.into_iter().map(|submit| {
139 assert_eq!(submit.family(), family);
140 submit.raw()
141 }),
142 wait_semaphores: submission.waits.into_iter().map(|w| (w.0.borrow(), w.1)),
143 signal_semaphores: submission.signals.into_iter().map(|s| s.borrow()),
144 },
145 submissions.peek().map_or(fence, |_| None),
146 );
147 }
148 }
149 }
150
151 pub fn wait_idle(&self) -> Result<(), rendy_core::hal::device::OutOfMemory> {
153 self.raw.wait_idle()
154 }
155}