use smallvec::SmallVec;
use std::any::Any;
use std::borrow::Cow;
use std::mem;
use std::ptr;
use std::sync::Arc;
use buffer::BufferAccess;
use command_buffer::CommandBuffer;
use command_buffer::synced::base::Command;
use command_buffer::synced::base::FinalCommand;
use command_buffer::synced::base::KeyTy;
use command_buffer::synced::base::SyncCommandBufferBuilder;
use command_buffer::synced::base::SyncCommandBufferBuilderError;
use command_buffer::sys::UnsafeCommandBufferBuilder;
use command_buffer::sys::UnsafeCommandBufferBuilderBindVertexBuffer;
use command_buffer::sys::UnsafeCommandBufferBuilderBufferImageCopy;
use command_buffer::sys::UnsafeCommandBufferBuilderColorImageClear;
use command_buffer::sys::UnsafeCommandBufferBuilderExecuteCommands;
use command_buffer::sys::UnsafeCommandBufferBuilderImageCopy;
use command_buffer::sys::UnsafeCommandBufferBuilderImageBlit;
use descriptor::descriptor::DescriptorDescTy;
use descriptor::descriptor::ShaderStages;
use descriptor::descriptor_set::DescriptorSet;
use descriptor::pipeline_layout::PipelineLayoutAbstract;
use format::ClearValue;
use framebuffer::FramebufferAbstract;
use framebuffer::SubpassContents;
use image::ImageAccess;
use image::ImageLayout;
use pipeline::ComputePipelineAbstract;
use pipeline::GraphicsPipelineAbstract;
use pipeline::input_assembly::IndexType;
use pipeline::viewport::Scissor;
use pipeline::viewport::Viewport;
use pipeline::depth_stencil::DynamicStencilValue;
use pipeline::depth_stencil::StencilFaceFlags;
use sampler::Filter;
use sync::AccessFlagBits;
use sync::Event;
use sync::PipelineStages;
impl<P> SyncCommandBufferBuilder<P> {
#[inline]
pub unsafe fn begin_render_pass<F, I>(&mut self, framebuffer: F,
subpass_contents: SubpassContents, clear_values: I)
-> Result<(), SyncCommandBufferBuilderError>
where F: FramebufferAbstract + Send + Sync + 'static,
I: Iterator<Item = ClearValue> + Send + Sync + 'static
{
struct Cmd<F, I> {
framebuffer: F,
subpass_contents: SubpassContents,
clear_values: Option<I>,
}
impl<P, F, I> Command<P> for Cmd<F, I>
where F: FramebufferAbstract + Send + Sync + 'static,
I: Iterator<Item = ClearValue>
{
fn name(&self) -> &'static str {
"vkCmdBeginRenderPass"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.begin_render_pass(&self.framebuffer,
self.subpass_contents,
self.clear_values.take().unwrap());
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<F>(F);
impl<F> FinalCommand for Fin<F>
where F: FramebufferAbstract + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBeginRenderPass"
}
fn image(&self, num: usize) -> &dyn ImageAccess {
self.0.attached_image_view(num).unwrap().parent()
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
format!("attachment {}", num).into()
}
}
Box::new(Fin(self.framebuffer))
}
fn image(&self, num: usize) -> &dyn ImageAccess {
self.framebuffer.attached_image_view(num).unwrap().parent()
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
format!("attachment {}", num).into()
}
}
let atch_desc = (0 .. framebuffer.num_attachments())
.map(|atch| framebuffer.attachment_desc(atch).unwrap())
.collect::<Vec<_>>();
self.append_command(Cmd {
framebuffer,
subpass_contents,
clear_values: Some(clear_values),
});
for (atch, desc) in atch_desc.into_iter().enumerate() {
self.prev_cmd_resource(KeyTy::Image, atch, true,
PipelineStages {
all_commands: true,
.. PipelineStages::none()
},
AccessFlagBits {
input_attachment_read: true,
color_attachment_read: true,
color_attachment_write: true,
depth_stencil_attachment_read: true,
depth_stencil_attachment_write: true,
.. AccessFlagBits::none()
},
desc.initial_layout, desc.final_layout)?;
}
self.prev_cmd_entered_render_pass();
Ok(())
}
#[inline]
pub unsafe fn bind_index_buffer<B>(&mut self, buffer: B, index_ty: IndexType)
-> Result<(), SyncCommandBufferBuilderError>
where B: BufferAccess + Send + Sync + 'static
{
struct Cmd<B> {
buffer: B,
index_ty: IndexType,
}
impl<P, B> Command<P> for Cmd<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBindIndexBuffer"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.bind_index_buffer(&self.buffer, self.index_ty);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<B>(B);
impl<B> FinalCommand for Fin<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBindIndexBuffer"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.0
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"index buffer".into()
}
}
Box::new(Fin(self.buffer))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.buffer
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"index buffer".into()
}
}
self.append_command(Cmd { buffer, index_ty });
self.prev_cmd_resource(KeyTy::Buffer,
0,
false,
PipelineStages {
vertex_input: true,
..PipelineStages::none()
},
AccessFlagBits {
index_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
Ok(())
}
#[inline]
pub unsafe fn bind_pipeline_graphics<Gp>(&mut self, pipeline: Gp)
where Gp: GraphicsPipelineAbstract + Send + Sync + 'static
{
struct Cmd<Gp> {
pipeline: Gp,
}
impl<P, Gp> Command<P> for Cmd<Gp>
where Gp: GraphicsPipelineAbstract + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBindPipeline"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.bind_pipeline_graphics(&self.pipeline);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<Gp>(Gp);
impl<Gp> FinalCommand for Fin<Gp>
where Gp: Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBindPipeline"
}
}
Box::new(Fin(self.pipeline))
}
}
self.append_command(Cmd { pipeline });
}
#[inline]
pub unsafe fn bind_pipeline_compute<Cp>(&mut self, pipeline: Cp)
where Cp: ComputePipelineAbstract + Send + Sync + 'static
{
struct Cmd<Gp> {
pipeline: Gp,
}
impl<P, Gp> Command<P> for Cmd<Gp>
where Gp: ComputePipelineAbstract + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBindPipeline"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.bind_pipeline_compute(&self.pipeline);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<Cp>(Cp);
impl<Cp> FinalCommand for Fin<Cp>
where Cp: Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBindPipeline"
}
}
Box::new(Fin(self.pipeline))
}
}
self.append_command(Cmd { pipeline });
}
#[inline]
pub fn bind_descriptor_sets(&mut self) -> SyncCommandBufferBuilderBindDescriptorSets<P> {
SyncCommandBufferBuilderBindDescriptorSets {
builder: self,
inner: SmallVec::new(),
}
}
#[inline]
pub fn bind_vertex_buffers(&mut self) -> SyncCommandBufferBuilderBindVertexBuffer<P> {
SyncCommandBufferBuilderBindVertexBuffer {
builder: self,
inner: UnsafeCommandBufferBuilderBindVertexBuffer::new(),
buffers: Vec::new(),
}
}
#[inline]
pub unsafe fn copy_image<S, D, R>(&mut self, source: S, source_layout: ImageLayout,
destination: D, destination_layout: ImageLayout, regions: R)
-> Result<(), SyncCommandBufferBuilderError>
where S: ImageAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderImageCopy> + Send + Sync + 'static
{
struct Cmd<S, D, R> {
source: Option<S>,
source_layout: ImageLayout,
destination: Option<D>,
destination_layout: ImageLayout,
regions: Option<R>,
}
impl<P, S, D, R> Command<P> for Cmd<S, D, R>
where S: ImageAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderImageCopy>
{
fn name(&self) -> &'static str {
"vkCmdCopyImage"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.copy_image(self.source.as_ref().unwrap(),
self.source_layout,
self.destination.as_ref().unwrap(),
self.destination_layout,
self.regions.take().unwrap());
}
fn into_final_command(mut self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<S, D>(S, D);
impl<S, D> FinalCommand for Fin<S, D>
where S: ImageAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdCopyImage"
}
fn image(&self, num: usize) -> &dyn ImageAccess {
if num == 0 {
&self.0
} else if num == 1 {
&self.1
} else {
panic!()
}
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
if num == 0 {
"source".into()
} else if num == 1 {
"destination".into()
} else {
panic!()
}
}
}
Box::new(Fin(self.source.take().unwrap(),
self.destination.take().unwrap()))
}
fn image(&self, num: usize) -> &dyn ImageAccess {
if num == 0 {
self.source.as_ref().unwrap()
} else if num == 1 {
self.destination.as_ref().unwrap()
} else {
panic!()
}
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
if num == 0 {
"source".into()
} else if num == 1 {
"destination".into()
} else {
panic!()
}
}
}
self.append_command(Cmd {
source: Some(source),
source_layout,
destination: Some(destination),
destination_layout,
regions: Some(regions),
});
self.prev_cmd_resource(KeyTy::Image,
0,
false,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_read: true,
..AccessFlagBits::none()
},
source_layout,
source_layout)?;
self.prev_cmd_resource(KeyTy::Image,
1,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
destination_layout,
destination_layout)?;
Ok(())
}
#[inline]
pub unsafe fn blit_image<S, D, R>(&mut self, source: S, source_layout: ImageLayout,
destination: D, destination_layout: ImageLayout, regions: R,
filter: Filter)
-> Result<(), SyncCommandBufferBuilderError>
where S: ImageAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderImageBlit> + Send + Sync + 'static
{
struct Cmd<S, D, R> {
source: Option<S>,
source_layout: ImageLayout,
destination: Option<D>,
destination_layout: ImageLayout,
regions: Option<R>,
filter: Filter,
}
impl<P, S, D, R> Command<P> for Cmd<S, D, R>
where S: ImageAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderImageBlit>
{
fn name(&self) -> &'static str {
"vkCmdBlitImage"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.blit_image(self.source.as_ref().unwrap(),
self.source_layout,
self.destination.as_ref().unwrap(),
self.destination_layout,
self.regions.take().unwrap(),
self.filter);
}
fn into_final_command(mut self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<S, D>(S, D);
impl<S, D> FinalCommand for Fin<S, D>
where S: ImageAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdBlitImage"
}
fn image(&self, num: usize) -> &dyn ImageAccess {
if num == 0 {
&self.0
} else if num == 1 {
&self.1
} else {
panic!()
}
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
if num == 0 {
"source".into()
} else if num == 1 {
"destination".into()
} else {
panic!()
}
}
}
Box::new(Fin(self.source.take().unwrap(),
self.destination.take().unwrap()))
}
fn image(&self, num: usize) -> &dyn ImageAccess {
if num == 0 {
self.source.as_ref().unwrap()
} else if num == 1 {
self.destination.as_ref().unwrap()
} else {
panic!()
}
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
if num == 0 {
"source".into()
} else if num == 1 {
"destination".into()
} else {
panic!()
}
}
}
self.append_command(Cmd {
source: Some(source),
source_layout,
destination: Some(destination),
destination_layout,
regions: Some(regions),
filter,
});
self.prev_cmd_resource(KeyTy::Image,
0,
false,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_read: true,
..AccessFlagBits::none()
},
source_layout,
source_layout)?;
self.prev_cmd_resource(KeyTy::Image,
1,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
destination_layout,
destination_layout)?;
Ok(())
}
pub unsafe fn clear_color_image<I, R>(&mut self, image: I, layout: ImageLayout,
color: ClearValue, regions: R)
-> Result<(), SyncCommandBufferBuilderError>
where I: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderColorImageClear> + Send + Sync + 'static
{
struct Cmd<I, R> {
image: Option<I>,
layout: ImageLayout,
color: ClearValue,
regions: Option<R>,
}
impl<P, I, R> Command<P> for Cmd<I, R>
where I: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderColorImageClear>
+ Send
+ Sync
+ 'static
{
fn name(&self) -> &'static str {
"vkCmdClearColorImage"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.clear_color_image(self.image.as_ref().unwrap(),
self.layout,
self.color,
self.regions.take().unwrap());
}
fn into_final_command(mut self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<I>(I);
impl<I> FinalCommand for Fin<I>
where I: ImageAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdClearColorImage"
}
fn image(&self, num: usize) -> &dyn ImageAccess {
assert_eq!(num, 0);
&self.0
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"target".into()
}
}
Box::new(Fin(self.image.take().unwrap()))
}
fn image(&self, num: usize) -> &dyn ImageAccess {
assert_eq!(num, 0);
self.image.as_ref().unwrap()
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"target".into()
}
}
self.append_command(Cmd {
image: Some(image),
layout,
color,
regions: Some(regions),
});
self.prev_cmd_resource(KeyTy::Image,
0,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
layout,
layout)?;
Ok(())
}
#[inline]
pub unsafe fn copy_buffer<S, D, R>(&mut self, source: S, destination: D, regions: R)
-> Result<(), SyncCommandBufferBuilderError>
where S: BufferAccess + Send + Sync + 'static,
D: BufferAccess + Send + Sync + 'static,
R: Iterator<Item = (usize, usize, usize)> + Send + Sync + 'static
{
struct Cmd<S, D, R> {
source: Option<S>,
destination: Option<D>,
regions: Option<R>,
}
impl<P, S, D, R> Command<P> for Cmd<S, D, R>
where S: BufferAccess + Send + Sync + 'static,
D: BufferAccess + Send + Sync + 'static,
R: Iterator<Item = (usize, usize, usize)>
{
fn name(&self) -> &'static str {
"vkCmdCopyBuffer"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.copy_buffer(self.source.as_ref().unwrap(),
self.destination.as_ref().unwrap(),
self.regions.take().unwrap());
}
fn into_final_command(mut self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<S, D>(S, D);
impl<S, D> FinalCommand for Fin<S, D>
where S: BufferAccess + Send + Sync + 'static,
D: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdCopyBuffer"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
match num {
0 => &self.0,
1 => &self.1,
_ => panic!(),
}
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
match num {
0 => "source".into(),
1 => "destination".into(),
_ => panic!(),
}
}
}
Box::new(Fin(self.source.take().unwrap(),
self.destination.take().unwrap()))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
match num {
0 => self.source.as_ref().unwrap(),
1 => self.destination.as_ref().unwrap(),
_ => panic!(),
}
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
match num {
0 => "source".into(),
1 => "destination".into(),
_ => panic!(),
}
}
}
self.append_command(Cmd {
source: Some(source),
destination: Some(destination),
regions: Some(regions),
});
self.prev_cmd_resource(KeyTy::Buffer,
0,
false,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
self.prev_cmd_resource(KeyTy::Buffer,
1,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
Ok(())
}
#[inline]
pub unsafe fn copy_buffer_to_image<S, D, R>(&mut self, source: S, destination: D,
destination_layout: ImageLayout, regions: R)
-> Result<(), SyncCommandBufferBuilderError>
where S: BufferAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderBufferImageCopy> + Send + Sync + 'static
{
struct Cmd<S, D, R> {
source: Option<S>,
destination: Option<D>,
destination_layout: ImageLayout,
regions: Option<R>,
}
impl<P, S, D, R> Command<P> for Cmd<S, D, R>
where S: BufferAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderBufferImageCopy>
{
fn name(&self) -> &'static str {
"vkCmdCopyBufferToImage"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.copy_buffer_to_image(self.source.as_ref().unwrap(),
self.destination.as_ref().unwrap(),
self.destination_layout,
self.regions.take().unwrap());
}
fn into_final_command(mut self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<S, D>(S, D);
impl<S, D> FinalCommand for Fin<S, D>
where S: BufferAccess + Send + Sync + 'static,
D: ImageAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdCopyBufferToImage"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.0
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"source".into()
}
fn image(&self, num: usize) -> &dyn ImageAccess {
assert_eq!(num, 0);
&self.1
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"destination".into()
}
}
Box::new(Fin(self.source.take().unwrap(),
self.destination.take().unwrap()))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
self.source.as_ref().unwrap()
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"source".into()
}
fn image(&self, num: usize) -> &dyn ImageAccess {
assert_eq!(num, 0);
self.destination.as_ref().unwrap()
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"destination".into()
}
}
self.append_command(Cmd {
source: Some(source),
destination: Some(destination),
destination_layout: destination_layout,
regions: Some(regions),
});
self.prev_cmd_resource(KeyTy::Buffer,
0,
false,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
self.prev_cmd_resource(KeyTy::Image,
0,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
destination_layout,
destination_layout)?;
Ok(())
}
#[inline]
pub unsafe fn copy_image_to_buffer<S, D, R>(&mut self, source: S, source_layout: ImageLayout,
destination: D, regions: R)
-> Result<(), SyncCommandBufferBuilderError>
where S: ImageAccess + Send + Sync + 'static,
D: BufferAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderBufferImageCopy> + Send + Sync + 'static
{
struct Cmd<S, D, R> {
source: Option<S>,
source_layout: ImageLayout,
destination: Option<D>,
regions: Option<R>,
}
impl<P, S, D, R> Command<P> for Cmd<S, D, R>
where S: ImageAccess + Send + Sync + 'static,
D: BufferAccess + Send + Sync + 'static,
R: Iterator<Item = UnsafeCommandBufferBuilderBufferImageCopy>
{
fn name(&self) -> &'static str {
"vkCmdCopyImageToBuffer"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.copy_image_to_buffer(self.source.as_ref().unwrap(),
self.source_layout,
self.destination.as_ref().unwrap(),
self.regions.take().unwrap());
}
fn into_final_command(mut self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<S, D>(S, D);
impl<S, D> FinalCommand for Fin<S, D>
where S: ImageAccess + Send + Sync + 'static,
D: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdCopyImageToBuffer"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.1
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"destination".into()
}
fn image(&self, num: usize) -> &dyn ImageAccess {
assert_eq!(num, 0);
&self.0
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"source".into()
}
}
Box::new(Fin(self.source.take().unwrap(),
self.destination.take().unwrap()))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
self.destination.as_ref().unwrap()
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"destination".into()
}
fn image(&self, num: usize) -> &dyn ImageAccess {
assert_eq!(num, 0);
self.source.as_ref().unwrap()
}
fn image_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"source".into()
}
}
self.append_command(Cmd {
source: Some(source),
destination: Some(destination),
source_layout: source_layout,
regions: Some(regions),
});
self.prev_cmd_resource(KeyTy::Image,
0,
false,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_read: true,
..AccessFlagBits::none()
},
source_layout,
source_layout)?;
self.prev_cmd_resource(KeyTy::Buffer,
0,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
Ok(())
}
#[inline]
pub unsafe fn dispatch(&mut self, dimensions: [u32; 3]) {
struct Cmd {
dimensions: [u32; 3],
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdDispatch"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.dispatch(self.dimensions);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdDispatch")
}
}
self.append_command(Cmd { dimensions });
}
#[inline]
pub unsafe fn dispatch_indirect<B>(&mut self, buffer: B)
-> Result<(), SyncCommandBufferBuilderError>
where B: BufferAccess + Send + Sync + 'static
{
struct Cmd<B> {
buffer: B,
}
impl<P, B> Command<P> for Cmd<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdDispatchIndirect"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.dispatch_indirect(&self.buffer);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<B>(B);
impl<B> FinalCommand for Fin<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdDispatchIndirect"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.0
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"indirect buffer".into()
}
}
Box::new(Fin(self.buffer))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.buffer
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"indirect buffer".into()
}
}
self.append_command(Cmd { buffer });
self.prev_cmd_resource(KeyTy::Buffer,
0,
false,
PipelineStages {
draw_indirect: true,
..PipelineStages::none()
},
AccessFlagBits {
indirect_command_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
Ok(())
}
#[inline]
pub unsafe fn draw(&mut self, vertex_count: u32, instance_count: u32, first_vertex: u32,
first_instance: u32) {
struct Cmd {
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
first_instance: u32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdDraw"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.draw(self.vertex_count,
self.instance_count,
self.first_vertex,
self.first_instance);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdDraw")
}
}
self.append_command(Cmd {
vertex_count,
instance_count,
first_vertex,
first_instance,
});
}
#[inline]
pub unsafe fn draw_indexed(&mut self, index_count: u32, instance_count: u32,
first_index: u32, vertex_offset: i32, first_instance: u32) {
struct Cmd {
index_count: u32,
instance_count: u32,
first_index: u32,
vertex_offset: i32,
first_instance: u32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdDrawIndexed"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.draw_indexed(self.index_count,
self.instance_count,
self.first_index,
self.vertex_offset,
self.first_instance);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdDrawIndexed")
}
}
self.append_command(Cmd {
index_count,
instance_count,
first_index,
vertex_offset,
first_instance,
});
}
#[inline]
pub unsafe fn draw_indirect<B>(&mut self, buffer: B, draw_count: u32, stride: u32)
-> Result<(), SyncCommandBufferBuilderError>
where B: BufferAccess + Send + Sync + 'static
{
struct Cmd<B> {
buffer: B,
draw_count: u32,
stride: u32,
}
impl<P, B> Command<P> for Cmd<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdDrawIndirect"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.draw_indirect(&self.buffer, self.draw_count, self.stride);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<B>(B);
impl<B> FinalCommand for Fin<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdDrawIndirect"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.0
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"indirect buffer".into()
}
}
Box::new(Fin(self.buffer))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.buffer
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"indirect buffer".into()
}
}
self.append_command(Cmd {
buffer,
draw_count,
stride,
});
self.prev_cmd_resource(KeyTy::Buffer,
0,
false,
PipelineStages {
draw_indirect: true,
..PipelineStages::none()
},
AccessFlagBits {
indirect_command_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
Ok(())
}
#[inline]
pub unsafe fn draw_indexed_indirect<B>(&mut self, buffer: B, draw_count: u32, stride: u32)
-> Result<(), SyncCommandBufferBuilderError>
where B: BufferAccess + Send + Sync + 'static
{
struct Cmd<B> {
buffer: B,
draw_count: u32,
stride: u32,
}
impl<P, B> Command<P> for Cmd<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdDrawIndexedIndirect"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.draw_indexed_indirect(&self.buffer, self.draw_count, self.stride);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<B>(B);
impl<B> FinalCommand for Fin<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdDrawIndexedIndirect"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.0
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"indirect buffer".into()
}
}
Box::new(Fin(self.buffer))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.buffer
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
assert_eq!(num, 0);
"indirect buffer".into()
}
}
self.append_command(Cmd {
buffer,
draw_count,
stride,
});
self.prev_cmd_resource(KeyTy::Buffer,
0,
false,
PipelineStages {
draw_indirect: true,
..PipelineStages::none()
},
AccessFlagBits {
indirect_command_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
Ok(())
}
#[inline]
pub unsafe fn end_render_pass(&mut self) {
struct Cmd;
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdEndRenderPass"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.end_render_pass();
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdEndRenderPass")
}
}
self.append_command(Cmd);
self.prev_cmd_left_render_pass();
}
#[inline]
pub unsafe fn execute_commands(&mut self) -> SyncCommandBufferBuilderExecuteCommands<P> {
SyncCommandBufferBuilderExecuteCommands {
builder: self,
inner: UnsafeCommandBufferBuilderExecuteCommands::new(),
command_buffers: Vec::new(),
}
}
#[inline]
pub unsafe fn fill_buffer<B>(&mut self, buffer: B, data: u32)
where B: BufferAccess + Send + Sync + 'static
{
struct Cmd<B> {
buffer: B,
data: u32,
}
impl<P, B> Command<P> for Cmd<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdFillBuffer"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.fill_buffer(&self.buffer, self.data);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<B>(B);
impl<B> FinalCommand for Fin<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdFillBuffer"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.0
}
fn buffer_name(&self, _: usize) -> Cow<'static, str> {
"destination".into()
}
}
Box::new(Fin(self.buffer))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.buffer
}
fn buffer_name(&self, _: usize) -> Cow<'static, str> {
"destination".into()
}
}
self.append_command(Cmd { buffer, data });
self.prev_cmd_resource(KeyTy::Buffer,
0,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)
.unwrap();
}
#[inline]
pub unsafe fn next_subpass(&mut self, subpass_contents: SubpassContents) {
struct Cmd {
subpass_contents: SubpassContents,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdNextSubpass"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.next_subpass(self.subpass_contents);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdNextSubpass")
}
}
self.append_command(Cmd { subpass_contents });
}
#[inline]
pub unsafe fn push_constants<Pl, D>(&mut self, pipeline_layout: Pl, stages: ShaderStages,
offset: u32, size: u32, data: &D)
where Pl: PipelineLayoutAbstract + Send + Sync + 'static,
D: ?Sized + Send + Sync + 'static
{
struct Cmd<Pl> {
pipeline_layout: Pl,
stages: ShaderStages,
offset: u32,
size: u32,
data: Box<[u8]>,
}
impl<P, Pl> Command<P> for Cmd<Pl>
where Pl: PipelineLayoutAbstract + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdPushConstants"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.push_constants::<_, [u8]>(&self.pipeline_layout,
self.stages,
self.offset,
self.size,
&self.data);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<Pl>(Pl);
impl<Pl> FinalCommand for Fin<Pl>
where Pl: Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdPushConstants"
}
}
Box::new(Fin(self.pipeline_layout))
}
}
debug_assert!(mem::size_of_val(data) >= size as usize);
let mut out = Vec::with_capacity(size as usize);
ptr::copy::<u8>(data as *const D as *const u8,
out.as_mut_ptr(),
size as usize);
out.set_len(size as usize);
self.append_command(Cmd {
pipeline_layout,
stages,
offset,
size,
data: out.into(),
});
}
#[inline]
pub unsafe fn reset_event(&mut self, event: Arc<Event>, stages: PipelineStages) {
struct Cmd {
event: Arc<Event>,
stages: PipelineStages,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdResetEvent"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.reset_event(&self.event, self.stages);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin(Arc<Event>);
impl FinalCommand for Fin {
fn name(&self) -> &'static str {
"vkCmdResetEvent"
}
}
Box::new(Fin(self.event))
}
}
self.append_command(Cmd { event, stages });
}
#[inline]
pub unsafe fn set_blend_constants(&mut self, constants: [f32; 4]) {
struct Cmd {
constants: [f32; 4],
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetBlendConstants"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_blend_constants(self.constants);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetBlendConstants")
}
}
self.append_command(Cmd { constants });
}
#[inline]
pub unsafe fn set_depth_bias(&mut self, constant_factor: f32, clamp: f32, slope_factor: f32) {
struct Cmd {
constant_factor: f32,
clamp: f32,
slope_factor: f32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetDepthBias"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_depth_bias(self.constant_factor, self.clamp, self.slope_factor);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetDepthBias")
}
}
self.append_command(Cmd {
constant_factor,
clamp,
slope_factor,
});
}
#[inline]
pub unsafe fn set_depth_bounds(&mut self, min: f32, max: f32) {
struct Cmd {
min: f32,
max: f32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetDepthBounds"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_depth_bounds(self.min, self.max);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetDepthBounds")
}
}
self.append_command(Cmd { min, max });
}
#[inline]
pub unsafe fn set_event(&mut self, event: Arc<Event>, stages: PipelineStages) {
struct Cmd {
event: Arc<Event>,
stages: PipelineStages,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetEvent"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_event(&self.event, self.stages);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin(Arc<Event>);
impl FinalCommand for Fin {
fn name(&self) -> &'static str {
"vkCmdSetEvent"
}
}
Box::new(Fin(self.event))
}
}
self.append_command(Cmd { event, stages });
}
#[inline]
pub unsafe fn set_line_width(&mut self, line_width: f32) {
struct Cmd {
line_width: f32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetLineWidth"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_line_width(self.line_width);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetLineWidth")
}
}
self.append_command(Cmd { line_width });
}
#[inline]
pub unsafe fn set_stencil_compare_mask(&mut self, compare_mask: DynamicStencilValue) {
struct Cmd {
face_mask: StencilFaceFlags,
compare_mask: u32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetStencilCompareMask"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_stencil_compare_mask(self.face_mask, self.compare_mask);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetStencilCompareMask")
}
}
self.append_command(Cmd {
face_mask: compare_mask.face,
compare_mask: compare_mask.value,
});
}
#[inline]
pub unsafe fn set_stencil_reference(&mut self, reference: DynamicStencilValue) {
struct Cmd {
face_mask: StencilFaceFlags,
reference: u32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetStencilReference"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_stencil_reference(self.face_mask, self.reference);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetStencilReference")
}
}
self.append_command(Cmd {
face_mask: reference.face,
reference: reference.value,
});
}
#[inline]
pub unsafe fn set_stencil_write_mask(&mut self, write_mask: DynamicStencilValue) {
struct Cmd {
face_mask: StencilFaceFlags,
write_mask: u32,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdSetStencilWriteMask"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_stencil_write_mask(self.face_mask, self.write_mask);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetStencilWriteMask")
}
}
self.append_command(Cmd {
face_mask: write_mask.face,
write_mask: write_mask.value,
});
}
#[inline]
pub unsafe fn set_scissor<I>(&mut self, first_scissor: u32, scissors: I)
where I: Iterator<Item = Scissor> + Send + Sync + 'static
{
struct Cmd<I> {
first_scissor: u32,
scissors: Option<I>,
}
impl<P, I> Command<P> for Cmd<I>
where I: Iterator<Item = Scissor>
{
fn name(&self) -> &'static str {
"vkCmdSetScissor"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_scissor(self.first_scissor, self.scissors.take().unwrap());
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetScissor")
}
}
self.append_command(Cmd {
first_scissor,
scissors: Some(scissors),
});
}
#[inline]
pub unsafe fn set_viewport<I>(&mut self, first_viewport: u32, viewports: I)
where I: Iterator<Item = Viewport> + Send + Sync + 'static
{
struct Cmd<I> {
first_viewport: u32,
viewports: Option<I>,
}
impl<P, I> Command<P> for Cmd<I>
where I: Iterator<Item = Viewport>
{
fn name(&self) -> &'static str {
"vkCmdSetViewport"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.set_viewport(self.first_viewport, self.viewports.take().unwrap());
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
Box::new("vkCmdSetViewport")
}
}
self.append_command(Cmd {
first_viewport,
viewports: Some(viewports),
});
}
#[inline]
pub unsafe fn update_buffer<B, D>(&mut self, buffer: B, data: D)
where B: BufferAccess + Send + Sync + 'static,
D: Send + Sync + 'static
{
struct Cmd<B, D> {
buffer: B,
data: D,
}
impl<P, B, D> Command<P> for Cmd<B, D>
where B: BufferAccess + Send + Sync + 'static,
D: Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdUpdateBuffer"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.update_buffer(&self.buffer, &self.data);
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin<B>(B);
impl<B> FinalCommand for Fin<B>
where B: BufferAccess + Send + Sync + 'static
{
fn name(&self) -> &'static str {
"vkCmdUpdateBuffer"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.0
}
fn buffer_name(&self, _: usize) -> Cow<'static, str> {
"destination".into()
}
}
Box::new(Fin(self.buffer))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
assert_eq!(num, 0);
&self.buffer
}
fn buffer_name(&self, _: usize) -> Cow<'static, str> {
"destination".into()
}
}
self.append_command(Cmd { buffer, data });
self.prev_cmd_resource(KeyTy::Buffer,
0,
true,
PipelineStages {
transfer: true,
..PipelineStages::none()
},
AccessFlagBits {
transfer_write: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)
.unwrap();
}
}
pub struct SyncCommandBufferBuilderBindDescriptorSets<'b, P: 'b> {
builder: &'b mut SyncCommandBufferBuilder<P>,
inner: SmallVec<[Box<dyn DescriptorSet + Send + Sync>; 12]>,
}
impl<'b, P> SyncCommandBufferBuilderBindDescriptorSets<'b, P> {
#[inline]
pub fn add<S>(&mut self, set: S)
where S: DescriptorSet + Send + Sync + 'static
{
self.inner.push(Box::new(set));
}
#[inline]
pub unsafe fn submit<Pl, I>(self, graphics: bool, pipeline_layout: Pl, first_binding: u32,
dynamic_offsets: I)
-> Result<(), SyncCommandBufferBuilderError>
where Pl: PipelineLayoutAbstract + Send + Sync + 'static,
I: Iterator<Item = u32> + Send + Sync + 'static
{
if self.inner.is_empty() {
return Ok(());
}
struct Cmd<Pl, I> {
inner: SmallVec<[Box<dyn DescriptorSet + Send + Sync>; 12]>,
graphics: bool,
pipeline_layout: Pl,
first_binding: u32,
dynamic_offsets: Option<I>,
}
impl<P, Pl, I> Command<P> for Cmd<Pl, I>
where Pl: PipelineLayoutAbstract,
I: Iterator<Item = u32>
{
fn name(&self) -> &'static str {
"vkCmdBindDescriptorSets"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.bind_descriptor_sets(self.graphics,
&self.pipeline_layout,
self.first_binding,
self.inner.iter().map(|s| s.inner()),
self.dynamic_offsets.take().unwrap());
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin(SmallVec<[Box<dyn DescriptorSet + Send + Sync>; 12]>);
impl FinalCommand for Fin {
fn name(&self) -> &'static str {
"vkCmdBindDescriptorSets"
}
fn buffer(&self, mut num: usize) -> &dyn BufferAccess {
for set in self.0.iter() {
if let Some(buf) = set.buffer(num) {
return buf.0;
}
num -= set.num_buffers();
}
panic!()
}
fn buffer_name(&self, mut num: usize) -> Cow<'static, str> {
for (set_num, set) in self.0.iter().enumerate() {
if let Some(buf) = set.buffer(num) {
return format!("Buffer bound to descriptor {} of set {}",
buf.1,
set_num)
.into();
}
num -= set.num_buffers();
}
panic!()
}
fn image(&self, mut num: usize) -> &dyn ImageAccess {
for set in self.0.iter() {
if let Some(img) = set.image(num) {
return img.0.parent();
}
num -= set.num_images();
}
panic!()
}
fn image_name(&self, mut num: usize) -> Cow<'static, str> {
for (set_num, set) in self.0.iter().enumerate() {
if let Some(img) = set.image(num) {
return format!("Image bound to descriptor {} of set {}",
img.1,
set_num)
.into();
}
num -= set.num_images();
}
panic!()
}
}
Box::new(Fin(self.inner))
}
fn buffer(&self, mut num: usize) -> &dyn BufferAccess {
for set in self.inner.iter() {
if let Some(buf) = set.buffer(num) {
return buf.0;
}
num -= set.num_buffers();
}
panic!()
}
fn buffer_name(&self, mut num: usize) -> Cow<'static, str> {
for (set_num, set) in self.inner.iter().enumerate() {
if let Some(buf) = set.buffer(num) {
return format!("Buffer bound to descriptor {} of set {}", buf.1, set_num)
.into();
}
num -= set.num_buffers();
}
panic!()
}
fn image(&self, mut num: usize) -> &dyn ImageAccess {
for set in self.inner.iter() {
if let Some(img) = set.image(num) {
return img.0.parent();
}
num -= set.num_images();
}
panic!()
}
fn image_name(&self, mut num: usize) -> Cow<'static, str> {
for (set_num, set) in self.inner.iter().enumerate() {
if let Some(img) = set.image(num) {
return format!("Image bound to descriptor {} of set {}", img.1, set_num)
.into();
}
num -= set.num_images();
}
panic!()
}
}
let all_buffers = {
let mut all_buffers = Vec::new();
for ds in self.inner.iter() {
for buf_num in 0 .. ds.num_buffers() {
let desc = ds.descriptor(ds.buffer(buf_num).unwrap().1 as usize)
.unwrap();
let write = !desc.readonly;
let (stages, access) = desc.pipeline_stages_and_access();
all_buffers.push((write, stages, access));
}
}
all_buffers
};
let all_images = {
let mut all_images = Vec::new();
for ds in self.inner.iter() {
for img_num in 0 .. ds.num_images() {
let (image_view, desc_num) = ds.image(img_num).unwrap();
let desc = ds.descriptor(desc_num as usize).unwrap();
let write = !desc.readonly;
let (stages, access) = desc.pipeline_stages_and_access();
let mut ignore_me_hack = false;
let layout = match desc.ty {
DescriptorDescTy::CombinedImageSampler(_) => {
image_view.descriptor_set_combined_image_sampler_layout()
},
DescriptorDescTy::Image(ref img) => {
if img.sampled {
image_view.descriptor_set_sampled_image_layout()
} else {
image_view.descriptor_set_storage_image_layout()
}
},
DescriptorDescTy::InputAttachment { .. } => {
ignore_me_hack = true;
image_view.descriptor_set_input_attachment_layout()
},
_ => panic!("Tried to bind an image to a non-image descriptor"),
};
all_images.push((write, stages, access, layout, ignore_me_hack));
}
}
all_images
};
self.builder.append_command(Cmd {
inner: self.inner,
graphics,
pipeline_layout,
first_binding,
dynamic_offsets: Some(dynamic_offsets),
});
for (n, (write, stages, access)) in all_buffers.into_iter().enumerate() {
self.builder
.prev_cmd_resource(KeyTy::Buffer,
n,
write,
stages,
access,
ImageLayout::Undefined,
ImageLayout::Undefined)?;
}
for (n, (write, stages, access, layout, ignore_me_hack)) in
all_images.into_iter().enumerate()
{
if ignore_me_hack {
continue;
}
self.builder
.prev_cmd_resource(KeyTy::Image, n, write, stages, access, layout, layout)?;
}
Ok(())
}
}
pub struct SyncCommandBufferBuilderBindVertexBuffer<'a, P: 'a> {
builder: &'a mut SyncCommandBufferBuilder<P>,
inner: UnsafeCommandBufferBuilderBindVertexBuffer,
buffers: Vec<Box<dyn BufferAccess + Send + Sync>>,
}
impl<'a, P> SyncCommandBufferBuilderBindVertexBuffer<'a, P> {
#[inline]
pub fn add<B>(&mut self, buffer: B)
where B: BufferAccess + Send + Sync + 'static
{
self.inner.add(&buffer);
self.buffers.push(Box::new(buffer));
}
#[inline]
pub unsafe fn submit(self, first_binding: u32) -> Result<(), SyncCommandBufferBuilderError> {
struct Cmd {
first_binding: u32,
inner: Option<UnsafeCommandBufferBuilderBindVertexBuffer>,
buffers: Vec<Box<dyn BufferAccess + Send + Sync>>,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdBindVertexBuffers"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.bind_vertex_buffers(self.first_binding, self.inner.take().unwrap());
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin(Vec<Box<dyn BufferAccess + Send + Sync>>);
impl FinalCommand for Fin {
fn name(&self) -> &'static str {
"vkCmdBindVertexBuffers"
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
&self.0[num]
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
format!("Buffer #{}", num).into()
}
}
Box::new(Fin(self.buffers))
}
fn buffer(&self, num: usize) -> &dyn BufferAccess {
&self.buffers[num]
}
fn buffer_name(&self, num: usize) -> Cow<'static, str> {
format!("Buffer #{}", num).into()
}
}
let num_buffers = self.buffers.len();
self.builder.append_command(Cmd {
first_binding,
inner: Some(self.inner),
buffers: self.buffers,
});
for n in 0 .. num_buffers {
self.builder
.prev_cmd_resource(KeyTy::Buffer,
n,
false,
PipelineStages {
vertex_input: true,
..PipelineStages::none()
},
AccessFlagBits {
vertex_attribute_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
}
Ok(())
}
}
pub struct SyncCommandBufferBuilderExecuteCommands<'a, P: 'a> {
builder: &'a mut SyncCommandBufferBuilder<P>,
inner: UnsafeCommandBufferBuilderExecuteCommands,
command_buffers: Vec<Box<dyn Any + Send + Sync>>,
}
impl<'a, P> SyncCommandBufferBuilderExecuteCommands<'a, P> {
#[inline]
pub fn add<C>(&mut self, command_buffer: C)
where C: CommandBuffer + Send + Sync + 'static
{
self.inner.add(&command_buffer);
self.command_buffers
.push(Box::new(command_buffer) as Box<_>);
}
#[inline]
pub unsafe fn submit(self) -> Result<(), SyncCommandBufferBuilderError> {
struct Cmd {
inner: Option<UnsafeCommandBufferBuilderExecuteCommands>,
command_buffers: Vec<Box<dyn Any + Send + Sync>>,
}
impl<P> Command<P> for Cmd {
fn name(&self) -> &'static str {
"vkCmdExecuteCommands"
}
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
out.execute_commands(self.inner.take().unwrap());
}
fn into_final_command(self: Box<Self>) -> Box<dyn FinalCommand + Send + Sync> {
struct Fin(Vec<Box<dyn Any + Send + Sync>>);
impl FinalCommand for Fin {
fn name(&self) -> &'static str {
"vkCmdExecuteCommands"
}
}
Box::new(Fin(self.command_buffers))
}
}
self.builder.append_command(Cmd {
inner: Some(self.inner),
command_buffers: self.command_buffers,
});
Ok(())
}
}