use {
crate::{buffer::*, capability::*, core::Device, family::FamilyId},
rendy_core::hal::{device::Device as _, pool::CommandPool as _, Backend},
};
#[derive(Debug)]
pub struct CommandPool<B: Backend, C = QueueType, R = NoIndividualReset> {
raw: B::CommandPool,
capability: C,
reset: R,
family: FamilyId,
relevant: relevant::Relevant,
}
family_owned!(CommandPool<B, C, R>);
impl<B, C, R> CommandPool<B, C, R>
where
B: Backend,
R: Reset,
{
pub unsafe fn create(
family: FamilyId,
capability: C,
device: &Device<B>,
) -> Result<Self, rendy_core::hal::device::OutOfMemory>
where
R: Reset,
C: Capability,
{
let reset = R::default();
let raw = device.create_command_pool(
rendy_core::hal::queue::QueueFamilyId(family.index),
reset.flags(),
)?;
Ok(CommandPool::from_raw(raw, capability, reset, family))
}
pub unsafe fn from_raw(raw: B::CommandPool, capability: C, reset: R, family: FamilyId) -> Self {
CommandPool {
raw,
capability,
reset,
family,
relevant: relevant::Relevant,
}
}
pub fn allocate_buffers<L: Level>(
&mut self,
count: usize,
) -> Vec<CommandBuffer<B, C, InitialState, L, R>>
where
L: Level,
C: Capability,
{
let level = L::default();
let buffers = unsafe { self.raw.allocate_vec(count, level.raw_level()) };
buffers
.into_iter()
.map(|raw| unsafe {
CommandBuffer::from_raw(
raw,
self.capability,
InitialState,
level,
self.reset,
self.family,
)
})
.collect()
}
pub unsafe fn free_buffers(
&mut self,
buffers: impl IntoIterator<Item = CommandBuffer<B, C, impl Resettable, impl Level, R>>,
) {
let buffers = buffers
.into_iter()
.map(|buffer| buffer.into_raw())
.collect::<Vec<_>>();
self.raw.free(buffers);
}
pub unsafe fn reset(&mut self) {
rendy_core::hal::pool::CommandPool::reset(&mut self.raw, false);
}
pub unsafe fn dispose(self, device: &Device<B>) {
self.assert_device_owner(device);
device.destroy_command_pool(self.raw);
self.relevant.dispose();
}
pub fn with_queue_type(self) -> CommandPool<B, QueueType, R>
where
C: Capability,
{
CommandPool {
raw: self.raw,
capability: self.capability.into_queue_type(),
reset: self.reset,
family: self.family,
relevant: self.relevant,
}
}
pub fn with_capability<U>(self) -> Result<CommandPool<B, U, R>, Self>
where
C: Supports<U>,
{
if let Some(capability) = self.capability.supports() {
Ok(CommandPool {
raw: self.raw,
capability,
reset: self.reset,
family: self.family,
relevant: self.relevant,
})
} else {
Err(self)
}
}
}