mod queue;
mod submission;
use crate::{
buffer::Reset,
capability::{Capability, Supports},
pool::CommandPool,
};
pub use self::{queue::*, submission::*};
pub type FamilyId = gfx_hal::queue::QueueFamilyId;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct QueueId(pub FamilyId, pub usize);
impl QueueId {
pub fn family(&self) -> FamilyId {
self.0
}
pub fn index(&self) -> usize {
self.1
}
}
#[derive(derivative::Derivative)]
#[derivative(Debug)]
pub struct Family<B: gfx_hal::Backend, C = gfx_hal::QueueType> {
id: FamilyId,
queues: Vec<Queue<B>>,
capability: C,
relevant: relevant::Relevant,
}
impl<B> Family<B>
where
B: gfx_hal::Backend,
{
pub unsafe fn from_device(
queues: &mut gfx_hal::queue::Queues<B>,
id: FamilyId,
count: usize,
family: &impl gfx_hal::queue::QueueFamily,
) -> Self {
Family {
id,
queues: {
let queues = queues.take_raw(id).expect("");
assert_eq!(queues.len(), count);
queues
.into_iter()
.enumerate()
.map(|(index, queue)| Queue::new(queue, QueueId(id, index)))
.collect()
},
capability: family.queue_type(),
relevant: relevant::Relevant,
}
}
}
impl<B, C> Family<B, C>
where
B: gfx_hal::Backend,
{
pub fn id(&self) -> FamilyId {
self.id
}
pub fn queues(&self) -> &[Queue<B>] {
&self.queues
}
pub fn queues_mut(&mut self) -> &mut [Queue<B>] {
&mut self.queues
}
pub fn create_pool<R>(
&self,
device: &impl gfx_hal::Device<B>,
) -> Result<CommandPool<B, C, R>, gfx_hal::device::OutOfMemory>
where
R: Reset,
C: Capability,
{
let reset = R::default();
let pool = unsafe {
let raw = device.create_command_pool(self.id, reset.flags())?;
CommandPool::from_raw(raw, self.capability, reset, self.id)
};
Ok(pool)
}
pub fn capability(&self) -> C
where
C: Capability,
{
self.capability
}
pub fn dispose(self) {
for queue in self.queues {
queue.wait_idle().unwrap();
}
self.relevant.dispose();
}
pub fn with_queue_type(self) -> Family<B, gfx_hal::QueueType>
where
C: Capability,
{
Family {
id: self.id,
queues: self.queues,
capability: self.capability.into_queue_type(),
relevant: self.relevant,
}
}
pub fn with_capability<U>(self) -> Result<Family<B, U>, Self>
where
C: Supports<U>,
{
if let Some(capability) = self.capability.supports() {
Ok(Family {
id: self.id,
queues: self.queues,
capability,
relevant: self.relevant,
})
} else {
Err(self)
}
}
}
pub unsafe fn families_from_device<B>(
queues: &mut gfx_hal::queue::Queues<B>,
families: impl IntoIterator<Item = (FamilyId, usize)>,
queue_types: &[impl gfx_hal::queue::QueueFamily],
) -> Vec<Family<B>>
where
B: gfx_hal::Backend,
{
families
.into_iter()
.map(|(index, count)| Family::from_device(queues, index, count, &queue_types[index.0]))
.collect()
}