1mod queue;
4mod submission;
5
6use {
7 crate::{
8 buffer::Reset,
9 capability::{Capability, QueueType, Supports},
10 core::{device_owned, Device, DeviceId},
11 pool::CommandPool,
12 },
13 rendy_core::hal::Backend,
14};
15
16pub use self::{queue::*, submission::*};
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
20pub struct FamilyId {
21 pub index: usize,
23
24 pub device: DeviceId,
26}
27
28impl From<FamilyId> for rendy_core::hal::queue::QueueFamilyId {
29 fn from(id: FamilyId) -> Self {
30 rendy_core::hal::queue::QueueFamilyId(id.index)
31 }
32}
33
34#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
36pub struct QueueId {
37 pub index: usize,
39
40 pub family: FamilyId,
42}
43
44#[derive(Debug)]
48pub struct Family<B: Backend, C = QueueType> {
49 id: FamilyId,
50 queues: Vec<Queue<B>>,
51 capability: C,
53}
54
55device_owned!(Family<B, C> @ |f: &Self| f.id.device);
56
57impl<B> Family<B, QueueType>
58where
59 B: Backend,
60{
61 pub unsafe fn from_device(
70 queue_groups: &mut Vec<rendy_core::hal::queue::QueueGroup<B>>,
71 id: FamilyId,
72 count: usize,
73 family: &impl rendy_core::hal::queue::QueueFamily,
74 ) -> Self {
75 Family {
76 id,
77 queues: {
78 let pos = queue_groups.iter().position(|qg| qg.family.0 == id.index);
79 let group = queue_groups.swap_remove(pos.unwrap());
80 assert_eq!(group.queues.len(), count);
81 group
82 .queues
83 .into_iter()
84 .enumerate()
85 .map(|(index, queue)| Queue::new(queue, QueueId { family: id, index }))
86 .collect()
87 },
88 capability: family.queue_type(),
90 }
91 }
92}
93
94impl<B, C> Family<B, C>
95where
96 B: Backend,
97{
98 pub fn id(&self) -> FamilyId {
100 self.id
101 }
102
103 pub fn queue(&self, index: usize) -> &Queue<B> {
105 &self.queues[index]
106 }
107
108 pub fn queue_mut(&mut self, index: usize) -> &mut Queue<B> {
110 &mut self.queues[index]
111 }
112
113 pub fn as_slice(&self) -> &[Queue<B>] {
115 &self.queues
116 }
117
118 pub fn as_slice_mut(&mut self) -> &mut [Queue<B>] {
120 &mut self.queues
121 }
122
123 pub fn create_pool<R>(
126 &self,
127 device: &Device<B>,
128 ) -> Result<CommandPool<B, C, R>, rendy_core::hal::device::OutOfMemory>
129 where
130 R: Reset,
131 C: Capability,
132 {
133 self.assert_device_owner(device);
134 unsafe { CommandPool::create(self.id, self.capability, device) }
135 }
136
137 pub fn capability(&self) -> C
139 where
140 C: Capability,
141 {
142 self.capability
143 }
144
145 pub fn with_queue_type(self) -> Family<B, QueueType>
147 where
148 C: Capability,
149 {
150 Family {
151 id: self.id,
152 queues: self.queues,
153 capability: self.capability.into_queue_type(),
155 }
156 }
157
158 pub fn with_capability<U>(self) -> Result<Family<B, U>, Self>
161 where
162 C: Supports<U>,
163 {
164 if let Some(capability) = self.capability.supports() {
165 Ok(Family {
166 id: self.id,
167 queues: self.queues,
168 capability,
170 })
171 } else {
172 Err(self)
173 }
174 }
175}
176
177#[derive(Debug)]
179pub struct Families<B: Backend> {
180 device: DeviceId,
181 families: Vec<Family<B>>,
182 families_indices: Vec<usize>,
183}
184
185impl<B> Families<B>
186where
187 B: Backend,
188{
189 pub fn family(&self, id: FamilyId) -> &Family<B> {
191 assert_eq!(id.device, self.device);
192 self.family_by_index(id.index)
193 }
194
195 pub fn family_by_index(&self, index: usize) -> &Family<B> {
197 &self.families[self.families_indices[index]]
198 }
199
200 pub fn family_mut(&mut self, id: FamilyId) -> &mut Family<B> {
202 assert_eq!(id.device, self.device);
203 self.family_by_index_mut(id.index)
204 }
205
206 pub fn family_by_index_mut(&mut self, index: usize) -> &mut Family<B> {
208 &mut self.families[self.families_indices[index]]
209 }
210
211 pub fn as_slice(&self) -> &[Family<B>] {
213 &self.families
214 }
215
216 pub fn as_slice_mut(&mut self) -> &mut [Family<B>] {
218 &mut self.families
219 }
220
221 pub fn indices(&self) -> &[usize] {
223 &self.families_indices
224 }
225
226 pub fn find<F>(&self, predicate: F) -> Option<FamilyId>
228 where
229 F: FnMut(&&Family<B>) -> bool,
230 {
231 self.families.iter().find(predicate).map(Family::id)
232 }
233
234 pub fn with_capability<C: Capability>(&self) -> Option<FamilyId> {
236 self.find(|family| Supports::<C>::supports(&family.capability()).is_some())
237 }
238}
239
240pub unsafe fn families_from_device<B>(
249 device: DeviceId,
250 queue_groups: &mut Vec<rendy_core::hal::queue::QueueGroup<B>>,
251 families: impl IntoIterator<Item = (FamilyId, usize)>,
252 queue_types: &[impl rendy_core::hal::queue::QueueFamily],
253) -> Families<B>
254where
255 B: Backend,
256{
257 let families: Vec<_> = families
258 .into_iter()
259 .map(|(id, count)| Family::from_device(queue_groups, id, count, &queue_types[id.index]))
260 .collect();
261
262 let mut families_indices = vec![!0; families.len()];
263 for (index, family) in families.iter().enumerate() {
264 families_indices[family.id.index] = index;
265 }
266
267 Families {
268 device,
269 families,
270 families_indices,
271 }
272}