use crate::queue::capability::{Capability, Supports};
use crate::Backend;
use std::borrow::Borrow;
use std::marker::PhantomData;
mod compute;
mod graphics;
mod raw;
mod render_pass;
mod transfer;
pub use self::graphics::*;
pub use self::raw::{
ClearColorRaw, ClearDepthStencilRaw, ClearValueRaw, CommandBufferFlags,
CommandBufferInheritanceInfo, DescriptorSetOffset, IntoRawCommandBuffer, Level as RawLevel,
RawCommandBuffer,
};
pub use self::render_pass::*;
pub use self::transfer::*;
pub trait Shot {}
pub enum OneShot {}
impl Shot for OneShot {}
pub enum MultiShot {}
impl Shot for MultiShot {}
pub trait Level {}
pub enum Primary {}
impl Level for Primary {}
pub enum Secondary {}
impl Level for Secondary {}
pub trait Submittable<B: Backend, C: Capability, L: Level>: Borrow<B::CommandBuffer> {}
pub type SecondaryCommandBuffer<B, C, S = OneShot> = CommandBuffer<B, C, S, Secondary>;
#[derive(Debug)]
pub struct CommandBuffer<B: Backend, C, S = OneShot, L = Primary, R = <B as Backend>::CommandBuffer>
{
pub(crate) raw: R,
pub(crate) _marker: PhantomData<(B, C, S, L)>,
}
impl<B, C, S, L, R> Borrow<R> for CommandBuffer<B, C, S, L, R>
where
R: RawCommandBuffer<B>,
B: Backend<CommandBuffer = R>,
{
fn borrow(&self) -> &B::CommandBuffer {
&self.raw
}
}
impl<B: Backend, C, K: Capability + Supports<C>, S, L: Level> Submittable<B, K, L>
for CommandBuffer<B, C, S, L>
{
}
impl<B: Backend, C, S, L> IntoRawCommandBuffer<B, C> for CommandBuffer<B, C, S, L> {
fn into_raw(self) -> B::CommandBuffer {
self.raw
}
}
impl<B: Backend, C> CommandBuffer<B, C, OneShot, Primary> {
pub unsafe fn begin(&mut self) {
let flags = CommandBufferFlags::ONE_TIME_SUBMIT;
self.raw
.begin(flags, CommandBufferInheritanceInfo::default());
}
}
impl<B: Backend, C> CommandBuffer<B, C, MultiShot, Primary> {
pub unsafe fn begin(&mut self, allow_pending_resubmit: bool) {
let flags = if allow_pending_resubmit {
CommandBufferFlags::SIMULTANEOUS_USE
} else {
CommandBufferFlags::empty()
};
self.raw
.begin(flags, CommandBufferInheritanceInfo::default());
}
}
impl<B: Backend, C> CommandBuffer<B, C, OneShot, Secondary> {
pub unsafe fn begin(&mut self, inheritance: CommandBufferInheritanceInfo<B>) {
let flags = CommandBufferFlags::ONE_TIME_SUBMIT;
self.raw.begin(flags, inheritance);
}
}
impl<B: Backend, C> CommandBuffer<B, C, MultiShot, Secondary> {
pub unsafe fn begin(
&mut self,
allow_pending_resubmit: bool,
inheritance: CommandBufferInheritanceInfo<B>,
) {
let flags = if allow_pending_resubmit {
CommandBufferFlags::SIMULTANEOUS_USE
} else {
CommandBufferFlags::empty()
};
self.raw.begin(flags, inheritance);
}
}
impl<B: Backend, C, S: Shot, L: Level> CommandBuffer<B, C, S, L> {
pub unsafe fn new(raw: B::CommandBuffer) -> Self {
CommandBuffer {
raw,
_marker: PhantomData,
}
}
pub unsafe fn finish(&mut self) {
self.raw.finish();
}
pub unsafe fn reset(&mut self, release_resources: bool) {
self.raw.reset(release_resources);
}
pub unsafe fn downgrade<D>(&mut self) -> &mut CommandBuffer<B, D, S>
where
C: Supports<D>,
{
::std::mem::transmute(self)
}
}
impl<B: Backend, C, S: Shot> CommandBuffer<B, C, S, Primary> {
pub unsafe fn execute_commands<'a, I, T, K>(&mut self, cmd_buffers: I)
where
K: Capability,
T: 'a + Submittable<B, K, Secondary>,
I: IntoIterator<Item = &'a T>,
C: Supports<K>,
{
self.raw
.execute_commands(cmd_buffers.into_iter().map(|cmb| cmb.borrow()));
}
}