diff options
Diffstat (limited to 'src/command_buffer/synced/commands.rs')
-rw-r--r-- | src/command_buffer/synced/commands.rs | 3123 |
1 files changed, 0 insertions, 3123 deletions
diff --git a/src/command_buffer/synced/commands.rs b/src/command_buffer/synced/commands.rs deleted file mode 100644 index 6b49a5a..0000000 --- a/src/command_buffer/synced/commands.rs +++ /dev/null @@ -1,3123 +0,0 @@ -// Copyright (c) 2016 The vulkano developers -// Licensed under the Apache License, Version 2.0 -// <LICENSE-APACHE or -// https://www.apache.org/licenses/LICENSE-2.0> or the MIT -// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, -// at your option. All files in the project carrying such -// notice may not be copied, modified, or distributed except -// according to those terms. - -use super::Command; -use crate::buffer::BufferAccess; -use crate::buffer::TypedBufferAccess; -use crate::command_buffer::synced::builder::KeyTy; -use crate::command_buffer::synced::builder::SyncCommandBufferBuilder; -use crate::command_buffer::synced::builder::SyncCommandBufferBuilderError; -use crate::command_buffer::sys::UnsafeCommandBufferBuilder; -use crate::command_buffer::sys::UnsafeCommandBufferBuilderBindVertexBuffer; -use crate::command_buffer::sys::UnsafeCommandBufferBuilderBufferImageCopy; -use crate::command_buffer::sys::UnsafeCommandBufferBuilderColorImageClear; -use crate::command_buffer::sys::UnsafeCommandBufferBuilderExecuteCommands; -use crate::command_buffer::sys::UnsafeCommandBufferBuilderImageBlit; -use crate::command_buffer::sys::UnsafeCommandBufferBuilderImageCopy; -use crate::command_buffer::CommandBufferExecError; -use crate::command_buffer::ImageUninitializedSafe; -use crate::command_buffer::SecondaryCommandBuffer; -use crate::command_buffer::SubpassContents; -use crate::descriptor_set::layout::DescriptorDescTy; -use crate::descriptor_set::DescriptorSet; -use crate::descriptor_set::DescriptorSetWithOffsets; -use crate::format::ClearValue; -use crate::image::ImageAccess; -use crate::image::ImageLayout; -use crate::pipeline::depth_stencil::StencilFaces; -use crate::pipeline::input_assembly::IndexType; -use crate::pipeline::layout::PipelineLayout; -use crate::pipeline::shader::ShaderStages; -use crate::pipeline::vertex::VertexInput; -use crate::pipeline::viewport::Scissor; -use crate::pipeline::viewport::Viewport; -use crate::pipeline::ComputePipelineAbstract; -use crate::pipeline::GraphicsPipelineAbstract; -use crate::pipeline::PipelineBindPoint; -use crate::query::QueryControlFlags; -use crate::query::QueryPool; -use crate::query::QueryResultElement; -use crate::query::QueryResultFlags; -use crate::render_pass::FramebufferAbstract; -use crate::render_pass::LoadOp; -use crate::sampler::Filter; -use crate::sync::AccessFlags; -use crate::sync::Event; -use crate::sync::PipelineMemoryAccess; -use crate::sync::PipelineStage; -use crate::sync::PipelineStages; -use crate::DeviceSize; -use crate::SafeDeref; -use crate::VulkanObject; -use smallvec::SmallVec; -use std::borrow::Cow; -use std::ffi::CStr; -use std::mem; -use std::ops::Range; -use std::ptr; -use std::sync::{Arc, Mutex}; - -impl SyncCommandBufferBuilder { - /// Calls `vkCmdBeginQuery` on the builder. - #[inline] - pub unsafe fn begin_query( - &mut self, - query_pool: Arc<QueryPool>, - query: u32, - flags: QueryControlFlags, - ) { - struct Cmd { - query_pool: Arc<QueryPool>, - query: u32, - flags: QueryControlFlags, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdBeginQuery" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.begin_query(self.query_pool.query(self.query).unwrap(), self.flags); - } - } - - self.append_command( - Cmd { - query_pool, - query, - flags, - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkBeginRenderPass` on the builder. - // TODO: it shouldn't be possible to get an error if the framebuffer checked conflicts already - // TODO: after begin_render_pass has been called, flushing should be forbidden and an error - // returned if conflict - #[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: IntoIterator<Item = ClearValue> + Send + Sync + 'static, - { - struct Cmd<F, I> { - framebuffer: F, - subpass_contents: SubpassContents, - clear_values: Mutex<Option<I>>, - } - - impl<F, I> Command for Cmd<F, I> - where - F: FramebufferAbstract + Send + Sync + 'static, - I: IntoIterator<Item = ClearValue>, - { - fn name(&self) -> &'static str { - "vkCmdBeginRenderPass" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.begin_render_pass( - &self.framebuffer, - self.subpass_contents, - self.clear_values.lock().unwrap().take().unwrap(), - ); - } - - fn image(&self, num: usize) -> &dyn ImageAccess { - self.framebuffer.attached_image_view(num).unwrap().image() - } - - fn image_name(&self, num: usize) -> Cow<'static, str> { - format!("attachment {}", num).into() - } - } - - let resources = framebuffer - .render_pass() - .desc() - .attachments() - .iter() - .map(|desc| { - ( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - all_commands: true, - ..PipelineStages::none() - }, // TODO: wrong! - access: AccessFlags { - input_attachment_read: true, - color_attachment_read: true, - color_attachment_write: true, - depth_stencil_attachment_read: true, - depth_stencil_attachment_write: true, - ..AccessFlags::none() - }, // TODO: suboptimal - exclusive: true, // TODO: suboptimal ; note: remember to always pass true if desc.initial_layout != desc.final_layout - }, - desc.initial_layout, - desc.final_layout, - match desc.initial_layout != ImageLayout::Undefined - || desc.load == LoadOp::Clear - { - true => ImageUninitializedSafe::Safe, - false => ImageUninitializedSafe::Unsafe, - }, - )), - ) - }) - .collect::<Vec<_>>(); - - self.append_command( - Cmd { - framebuffer, - subpass_contents, - clear_values: Mutex::new(Some(clear_values)), - }, - &resources, - )?; - - self.latest_render_pass_enter = Some(self.commands.len() - 1); - Ok(()) - } - - /// Starts the process of binding descriptor sets. Returns an intermediate struct which can be - /// used to add the sets. - #[inline] - pub fn bind_descriptor_sets(&mut self) -> SyncCommandBufferBuilderBindDescriptorSets { - SyncCommandBufferBuilderBindDescriptorSets { - builder: self, - descriptor_sets: SmallVec::new(), - } - } - - /// Calls `vkCmdBindIndexBuffer` on the builder. - #[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<B> Command for Cmd<B> - where - B: BufferAccess + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdBindIndexBuffer" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.bind_index_buffer(&self.buffer, self.index_ty); - } - - fn bound_index_buffer(&self) -> &dyn BufferAccess { - &self.buffer - } - } - - self.append_command(Cmd { buffer, index_ty }, &[])?; - self.bindings.index_buffer = self.commands.last().cloned(); - - Ok(()) - } - - /// Calls `vkCmdBindPipeline` on the builder with a compute 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<Gp> Command for Cmd<Gp> - where - Gp: ComputePipelineAbstract + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdBindPipeline" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.bind_pipeline_compute(&self.pipeline); - } - - fn bound_pipeline_compute(&self) -> &dyn ComputePipelineAbstract { - &self.pipeline - } - } - - self.append_command(Cmd { pipeline }, &[]).unwrap(); - self.bindings.pipeline_compute = self.commands.last().cloned(); - } - - /// Calls `vkCmdBindPipeline` on the builder with a graphics pipeline. - #[inline] - pub unsafe fn bind_pipeline_graphics<Gp>(&mut self, pipeline: Gp) - where - Gp: GraphicsPipelineAbstract + Send + Sync + 'static, - { - struct Cmd<Gp> { - pipeline: Gp, - } - - impl<Gp> Command for Cmd<Gp> - where - Gp: GraphicsPipelineAbstract + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdBindPipeline" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.bind_pipeline_graphics(&self.pipeline); - } - - fn bound_pipeline_graphics(&self) -> &dyn GraphicsPipelineAbstract { - &self.pipeline - } - } - - self.append_command(Cmd { pipeline }, &[]).unwrap(); - self.bindings.pipeline_graphics = self.commands.last().cloned(); - } - - /// Starts the process of binding vertex buffers. Returns an intermediate struct which can be - /// used to add the buffers. - #[inline] - pub fn bind_vertex_buffers(&mut self) -> SyncCommandBufferBuilderBindVertexBuffer { - SyncCommandBufferBuilderBindVertexBuffer { - builder: self, - inner: UnsafeCommandBufferBuilderBindVertexBuffer::new(), - buffers: SmallVec::new(), - } - } - - /// Calls `vkCmdCopyImage` on the builder. - /// - /// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid - /// usage of the command anyway. - #[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: IntoIterator<Item = UnsafeCommandBufferBuilderImageCopy> + Send + Sync + 'static, - { - struct Cmd<S, D, R> { - source: S, - source_layout: ImageLayout, - destination: D, - destination_layout: ImageLayout, - regions: Mutex<Option<R>>, - } - - impl<S, D, R> Command for Cmd<S, D, R> - where - S: ImageAccess + Send + Sync + 'static, - D: ImageAccess + Send + Sync + 'static, - R: IntoIterator<Item = UnsafeCommandBufferBuilderImageCopy>, - { - fn name(&self) -> &'static str { - "vkCmdCopyImage" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.copy_image( - &self.source, - self.source_layout, - &self.destination, - self.destination_layout, - self.regions.lock().unwrap().take().unwrap(), - ); - } - - fn image(&self, num: usize) -> &dyn ImageAccess { - if num == 0 { - &self.source - } else if num == 1 { - &self.destination - } 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, - source_layout, - destination, - destination_layout, - regions: Mutex::new(Some(regions)), - }, - &[ - ( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - source_layout, - source_layout, - ImageUninitializedSafe::Unsafe, - )), - ), - ( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - destination_layout, - destination_layout, - ImageUninitializedSafe::Safe, - )), - ), - ], - )?; - - Ok(()) - } - - /// Calls `vkCmdBlitImage` on the builder. - /// - /// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid - /// usage of the command anyway. - #[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: IntoIterator<Item = UnsafeCommandBufferBuilderImageBlit> + Send + Sync + 'static, - { - struct Cmd<S, D, R> { - source: S, - source_layout: ImageLayout, - destination: D, - destination_layout: ImageLayout, - regions: Mutex<Option<R>>, - filter: Filter, - } - - impl<S, D, R> Command for Cmd<S, D, R> - where - S: ImageAccess + Send + Sync + 'static, - D: ImageAccess + Send + Sync + 'static, - R: IntoIterator<Item = UnsafeCommandBufferBuilderImageBlit>, - { - fn name(&self) -> &'static str { - "vkCmdBlitImage" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.blit_image( - &self.source, - self.source_layout, - &self.destination, - self.destination_layout, - self.regions.lock().unwrap().take().unwrap(), - self.filter, - ); - } - - fn image(&self, num: usize) -> &dyn ImageAccess { - if num == 0 { - &self.source - } else if num == 1 { - &self.destination - } 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, - source_layout, - destination, - destination_layout, - regions: Mutex::new(Some(regions)), - filter, - }, - &[ - ( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - source_layout, - source_layout, - ImageUninitializedSafe::Unsafe, - )), - ), - ( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - destination_layout, - destination_layout, - ImageUninitializedSafe::Safe, - )), - ), - ], - )?; - - Ok(()) - } - - /// Calls `vkCmdClearColorImage` on the builder. - /// - /// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid - /// usage of the command anyway. - 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: IntoIterator<Item = UnsafeCommandBufferBuilderColorImageClear> + Send + Sync + 'static, - { - struct Cmd<I, R> { - image: I, - layout: ImageLayout, - color: ClearValue, - regions: Mutex<Option<R>>, - } - - impl<I, R> Command for Cmd<I, R> - where - I: ImageAccess + Send + Sync + 'static, - R: IntoIterator<Item = UnsafeCommandBufferBuilderColorImageClear> - + Send - + Sync - + 'static, - { - fn name(&self) -> &'static str { - "vkCmdClearColorImage" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.clear_color_image( - &self.image, - self.layout, - self.color, - self.regions.lock().unwrap().take().unwrap(), - ); - } - - fn image(&self, num: usize) -> &dyn ImageAccess { - assert_eq!(num, 0); - &self.image - } - - fn image_name(&self, num: usize) -> Cow<'static, str> { - assert_eq!(num, 0); - "target".into() - } - } - - self.append_command( - Cmd { - image, - layout, - color, - regions: Mutex::new(Some(regions)), - }, - &[( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - layout, - layout, - ImageUninitializedSafe::Safe, - )), - )], - )?; - - Ok(()) - } - - /// Calls `vkCmdCopyBuffer` on the builder. - /// - /// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid - /// usage of the command anyway. - #[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: IntoIterator<Item = (DeviceSize, DeviceSize, DeviceSize)> + Send + Sync + 'static, - { - struct Cmd<S, D, R> { - source: S, - destination: D, - regions: Mutex<Option<R>>, - } - - impl<S, D, R> Command for Cmd<S, D, R> - where - S: BufferAccess + Send + Sync + 'static, - D: BufferAccess + Send + Sync + 'static, - R: IntoIterator<Item = (DeviceSize, DeviceSize, DeviceSize)>, - { - fn name(&self) -> &'static str { - "vkCmdCopyBuffer" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.copy_buffer( - &self.source, - &self.destination, - self.regions.lock().unwrap().take().unwrap(), - ); - } - - fn buffer(&self, num: usize) -> &dyn BufferAccess { - match num { - 0 => &self.source, - 1 => &self.destination, - _ => panic!(), - } - } - - fn buffer_name(&self, num: usize) -> Cow<'static, str> { - match num { - 0 => "source".into(), - 1 => "destination".into(), - _ => panic!(), - } - } - } - - self.append_command( - Cmd { - source, - destination, - regions: Mutex::new(Some(regions)), - }, - &[ - ( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - ), - ( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - ), - ], - )?; - - Ok(()) - } - - /// Calls `vkCmdCopyBufferToImage` on the builder. - /// - /// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid - /// usage of the command anyway. - #[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: IntoIterator<Item = UnsafeCommandBufferBuilderBufferImageCopy> + Send + Sync + 'static, - { - struct Cmd<S, D, R> { - source: S, - destination: D, - destination_layout: ImageLayout, - regions: Mutex<Option<R>>, - } - - impl<S, D, R> Command for Cmd<S, D, R> - where - S: BufferAccess + Send + Sync + 'static, - D: ImageAccess + Send + Sync + 'static, - R: IntoIterator<Item = UnsafeCommandBufferBuilderBufferImageCopy>, - { - fn name(&self) -> &'static str { - "vkCmdCopyBufferToImage" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.copy_buffer_to_image( - &self.source, - &self.destination, - self.destination_layout, - self.regions.lock().unwrap().take().unwrap(), - ); - } - - fn buffer(&self, num: usize) -> &dyn BufferAccess { - assert_eq!(num, 0); - &self.source - } - - 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 - } - - fn image_name(&self, num: usize) -> Cow<'static, str> { - assert_eq!(num, 0); - "destination".into() - } - } - - self.append_command( - Cmd { - source, - destination, - destination_layout, - regions: Mutex::new(Some(regions)), - }, - &[ - ( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - ), - ( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - destination_layout, - destination_layout, - ImageUninitializedSafe::Safe, - )), - ), - ], - )?; - - Ok(()) - } - - /// Calls `vkCmdCopyImageToBuffer` on the builder. - /// - /// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid - /// usage of the command anyway. - #[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: IntoIterator<Item = UnsafeCommandBufferBuilderBufferImageCopy> + Send + Sync + 'static, - { - struct Cmd<S, D, R> { - source: S, - source_layout: ImageLayout, - destination: D, - regions: Mutex<Option<R>>, - } - - impl<S, D, R> Command for Cmd<S, D, R> - where - S: ImageAccess + Send + Sync + 'static, - D: BufferAccess + Send + Sync + 'static, - R: IntoIterator<Item = UnsafeCommandBufferBuilderBufferImageCopy>, - { - fn name(&self) -> &'static str { - "vkCmdCopyImageToBuffer" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.copy_image_to_buffer( - &self.source, - self.source_layout, - &self.destination, - self.regions.lock().unwrap().take().unwrap(), - ); - } - - fn buffer(&self, num: usize) -> &dyn BufferAccess { - assert_eq!(num, 0); - &self.destination - } - - 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 - } - - fn image_name(&self, num: usize) -> Cow<'static, str> { - assert_eq!(num, 0); - "source".into() - } - } - - self.append_command( - Cmd { - source, - destination, - source_layout, - regions: Mutex::new(Some(regions)), - }, - &[ - ( - KeyTy::Image, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - source_layout, - source_layout, - ImageUninitializedSafe::Unsafe, - )), - ), - ( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - ), - ], - )?; - - Ok(()) - } - - /// Calls `vkCmdCopyQueryPoolResults` on the builder. - /// - /// # Safety - /// `stride` must be at least the number of bytes that will be written by each query. - pub unsafe fn copy_query_pool_results<D, T>( - &mut self, - query_pool: Arc<QueryPool>, - queries: Range<u32>, - destination: D, - stride: DeviceSize, - flags: QueryResultFlags, - ) -> Result<(), SyncCommandBufferBuilderError> - where - D: BufferAccess + TypedBufferAccess<Content = [T]> + Send + Sync + 'static, - T: QueryResultElement, - { - struct Cmd<D> { - query_pool: Arc<QueryPool>, - queries: Range<u32>, - destination: D, - stride: DeviceSize, - flags: QueryResultFlags, - } - - impl<D, T> Command for Cmd<D> - where - D: BufferAccess + TypedBufferAccess<Content = [T]> + Send + Sync + 'static, - T: QueryResultElement, - { - fn name(&self) -> &'static str { - "vkCmdCopyQueryPoolResults" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.copy_query_pool_results( - self.query_pool.queries_range(self.queries.clone()).unwrap(), - &self.destination, - self.stride, - self.flags, - ); - } - - fn buffer(&self, num: usize) -> &dyn BufferAccess { - assert_eq!(num, 0); - &self.destination - } - - fn buffer_name(&self, num: usize) -> Cow<'static, str> { - assert_eq!(num, 0); - "destination".into() - } - } - - self.append_command( - Cmd { - query_pool, - queries, - destination, - stride, - flags, - }, - &[( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - )], - )?; - - Ok(()) - } - - /// Calls `vkCmdBeginDebugUtilsLabelEXT` on the builder. - /// - /// # Safety - /// The command pool that this command buffer was allocated from must support graphics or - /// compute operations - #[inline] - pub unsafe fn debug_marker_begin(&mut self, name: &'static CStr, color: [f32; 4]) { - struct Cmd { - name: &'static CStr, - color: [f32; 4], - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdBeginDebugUtilsLabelEXT" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.debug_marker_begin(self.name, self.color); - } - } - - self.append_command(Cmd { name, color }, &[]).unwrap(); - } - - /// Calls `vkCmdEndDebugUtilsLabelEXT` on the builder. - /// - /// # Safety - /// - The command pool that this command buffer was allocated from must support graphics or - /// compute operations - /// - There must be an outstanding `debug_marker_begin` command prior to the - /// `debug_marker_end` on the queue. - #[inline] - pub unsafe fn debug_marker_end(&mut self) { - struct Cmd {} - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdEndDebugUtilsLabelEXT" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.debug_marker_end(); - } - } - - self.append_command(Cmd {}, &[]).unwrap(); - } - - /// Calls `vkCmdInsertDebugUtilsLabelEXT` on the builder. - /// - /// # Safety - /// The command pool that this command buffer was allocated from must support graphics or - /// compute operations - #[inline] - pub unsafe fn debug_marker_insert(&mut self, name: &'static CStr, color: [f32; 4]) { - struct Cmd { - name: &'static CStr, - color: [f32; 4], - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdInsertDebugUtilsLabelEXT" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.debug_marker_insert(self.name, self.color); - } - } - - self.append_command(Cmd { name, color }, &[]).unwrap(); - } - - /// Calls `vkCmdDispatch` on the builder. - #[inline] - pub unsafe fn dispatch(&mut self, group_counts: [u32; 3]) { - struct Cmd { - group_counts: [u32; 3], - descriptor_sets: SmallVec<[Arc<dyn Command + Send + Sync>; 12]>, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdDispatch" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.dispatch(self.group_counts); - } - - fn buffer(&self, mut num: usize) -> &dyn BufferAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - 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 - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(buf) = set.buffer(num) { - return format!("Buffer bound to set {} descriptor {}", set_num, buf.1) - .into(); - } - num -= set.num_buffers(); - } - panic!() - } - - fn image(&self, mut num: usize) -> &dyn ImageAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(img) = set.image(num) { - return img.0.image(); - } - num -= set.num_images(); - } - panic!() - } - - fn image_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(img) = set.image(num) { - return format!("Image bound to set {} descriptor {}", set_num, img.1) - .into(); - } - num -= set.num_images(); - } - panic!() - } - } - - let pipeline = self - .bindings - .pipeline_compute - .as_ref() - .unwrap() - .bound_pipeline_compute(); - - let mut resources = Vec::new(); - let descriptor_sets = self.add_descriptor_set_resources( - &mut resources, - pipeline.layout(), - PipelineBindPoint::Compute, - ); - - self.append_command( - Cmd { - group_counts, - descriptor_sets, - }, - &resources, - ) - .unwrap(); - } - - /// Calls `vkCmdDispatchIndirect` on the builder. - #[inline] - pub unsafe fn dispatch_indirect<B>( - &mut self, - indirect_buffer: B, - ) -> Result<(), SyncCommandBufferBuilderError> - where - B: BufferAccess + Send + Sync + 'static, - { - struct Cmd<B> { - descriptor_sets: SmallVec<[Arc<dyn Command + Send + Sync>; 12]>, - indirect_buffer: B, - } - - impl<B> Command for Cmd<B> - where - B: BufferAccess + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdDispatchIndirect" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.dispatch_indirect(&self.indirect_buffer); - } - - fn buffer(&self, mut num: usize) -> &dyn BufferAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(buf) = set.buffer(num) { - return buf.0; - } - num -= set.num_buffers(); - } - if num == 0 { - return &self.indirect_buffer; - } - panic!() - } - - fn buffer_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(buf) = set.buffer(num) { - return format!("Buffer bound to set {} descriptor {}", set_num, buf.1) - .into(); - } - num -= set.num_buffers(); - } - if num == 0 { - return "indirect buffer".into(); - } - panic!() - } - - fn image(&self, mut num: usize) -> &dyn ImageAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(img) = set.image(num) { - return img.0.image(); - } - num -= set.num_images(); - } - panic!() - } - - fn image_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(img) = set.image(num) { - return format!("Image bound to set {} descriptor {}", set_num, img.1) - .into(); - } - num -= set.num_images(); - } - panic!() - } - } - - let pipeline = self - .bindings - .pipeline_compute - .as_ref() - .unwrap() - .bound_pipeline_compute(); - - let mut resources = Vec::new(); - let descriptor_sets = self.add_descriptor_set_resources( - &mut resources, - pipeline.layout(), - PipelineBindPoint::Compute, - ); - self.add_indirect_buffer_resources(&mut resources); - - self.append_command( - Cmd { - descriptor_sets, - indirect_buffer, - }, - &resources, - )?; - - Ok(()) - } - - /// Calls `vkCmdDraw` on the builder. - #[inline] - pub unsafe fn draw( - &mut self, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, - ) { - struct Cmd { - descriptor_sets: SmallVec<[Arc<dyn Command + Send + Sync>; 12]>, - vertex_buffers: SmallVec<[(u32, Arc<dyn Command + Send + Sync>); 4]>, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdDraw" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.draw( - self.vertex_count, - self.instance_count, - self.first_vertex, - self.first_instance, - ); - } - - fn buffer(&self, mut num: usize) -> &dyn BufferAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(buf) = set.buffer(num) { - return buf.0; - } - num -= set.num_buffers(); - } - - for buffer in self - .vertex_buffers - .iter() - .map(|(binding_num, cmd)| cmd.bound_vertex_buffer(*binding_num)) - { - if num == 0 { - return buffer; - } - num -= 1; - } - - panic!() - } - - fn buffer_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(buf) = set.buffer(num) { - return format!("Buffer bound to set {} descriptor {}", set_num, buf.1) - .into(); - } - num -= set.num_buffers(); - } - - for binding_num in self - .vertex_buffers - .iter() - .map(|(binding_num, _)| *binding_num) - { - if num == 0 { - return format!("Vertex buffer binding {}", binding_num).into(); - } - num -= 1; - } - - panic!() - } - - fn image(&self, mut num: usize) -> &dyn ImageAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(img) = set.image(num) { - return img.0.image(); - } - num -= set.num_images(); - } - panic!() - } - - fn image_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(img) = set.image(num) { - return format!("Image bound to set {} descriptor {}", set_num, img.1) - .into(); - } - num -= set.num_images(); - } - panic!() - } - } - - let pipeline = self - .bindings - .pipeline_graphics - .as_ref() - .unwrap() - .bound_pipeline_graphics(); - - let mut resources = Vec::new(); - let descriptor_sets = self.add_descriptor_set_resources( - &mut resources, - pipeline.layout(), - PipelineBindPoint::Graphics, - ); - let vertex_buffers = - self.add_vertex_buffer_resources(&mut resources, pipeline.vertex_input()); - - self.append_command( - Cmd { - descriptor_sets, - vertex_buffers, - vertex_count, - instance_count, - first_vertex, - first_instance, - }, - &resources, - ) - .unwrap(); - } - - /// Calls `vkCmdDrawIndexed` on the builder. - #[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 { - descriptor_sets: SmallVec<[Arc<dyn Command + Send + Sync>; 12]>, - vertex_buffers: SmallVec<[(u32, Arc<dyn Command + Send + Sync>); 4]>, - index_buffer: Arc<dyn Command + Send + Sync>, - index_count: u32, - instance_count: u32, - first_index: u32, - vertex_offset: i32, - first_instance: u32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdDrawIndexed" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.draw_indexed( - self.index_count, - self.instance_count, - self.first_index, - self.vertex_offset, - self.first_instance, - ); - } - - fn buffer(&self, mut num: usize) -> &dyn BufferAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(buf) = set.buffer(num) { - return buf.0; - } - num -= set.num_buffers(); - } - - for buffer in self - .vertex_buffers - .iter() - .map(|(binding_num, cmd)| cmd.bound_vertex_buffer(*binding_num)) - { - if num == 0 { - return buffer; - } - num -= 1; - } - - if num == 0 { - return self.index_buffer.bound_index_buffer(); - } - - panic!() - } - - fn buffer_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(buf) = set.buffer(num) { - return format!("Buffer bound to set {} descriptor {}", set_num, buf.1) - .into(); - } - num -= set.num_buffers(); - } - - for binding_num in self - .vertex_buffers - .iter() - .map(|(binding_num, _)| *binding_num) - { - if num == 0 { - return format!("Vertex buffer binding {}", binding_num).into(); - } - num -= 1; - } - - if num == 0 { - return "index buffer".into(); - } - - panic!() - } - - fn image(&self, mut num: usize) -> &dyn ImageAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(img) = set.image(num) { - return img.0.image(); - } - num -= set.num_images(); - } - panic!() - } - - fn image_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(img) = set.image(num) { - return format!("Image bound to set {} descriptor {}", set_num, img.1) - .into(); - } - num -= set.num_images(); - } - panic!() - } - } - - let pipeline = self - .bindings - .pipeline_graphics - .as_ref() - .unwrap() - .bound_pipeline_graphics(); - - let mut resources = Vec::new(); - let descriptor_sets = self.add_descriptor_set_resources( - &mut resources, - pipeline.layout(), - PipelineBindPoint::Graphics, - ); - let vertex_buffers = - self.add_vertex_buffer_resources(&mut resources, pipeline.vertex_input()); - let index_buffer = self.add_index_buffer_resources(&mut resources); - - self.append_command( - Cmd { - descriptor_sets, - vertex_buffers, - index_buffer, - index_count, - instance_count, - first_index, - vertex_offset, - first_instance, - }, - &resources, - ) - .unwrap(); - } - - /// Calls `vkCmdDrawIndirect` on the builder. - #[inline] - pub unsafe fn draw_indirect<B>( - &mut self, - indirect_buffer: B, - draw_count: u32, - stride: u32, - ) -> Result<(), SyncCommandBufferBuilderError> - where - B: BufferAccess + Send + Sync + 'static, - { - struct Cmd<B> { - descriptor_sets: SmallVec<[Arc<dyn Command + Send + Sync>; 12]>, - vertex_buffers: SmallVec<[(u32, Arc<dyn Command + Send + Sync>); 4]>, - indirect_buffer: B, - draw_count: u32, - stride: u32, - } - - impl<B> Command for Cmd<B> - where - B: BufferAccess + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdDrawIndirect" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.draw_indirect(&self.indirect_buffer, self.draw_count, self.stride); - } - - fn buffer(&self, mut num: usize) -> &dyn BufferAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(buf) = set.buffer(num) { - return buf.0; - } - num -= set.num_buffers(); - } - - for buffer in self - .vertex_buffers - .iter() - .map(|(binding_num, cmd)| cmd.bound_vertex_buffer(*binding_num)) - { - if num == 0 { - return buffer; - } - num -= 1; - } - - if num == 0 { - return &self.indirect_buffer; - } - - panic!() - } - - fn buffer_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(buf) = set.buffer(num) { - return format!("Buffer bound to set {} descriptor {}", set_num, buf.1) - .into(); - } - num -= set.num_buffers(); - } - - for binding_num in self - .vertex_buffers - .iter() - .map(|(binding_num, _)| *binding_num) - { - if num == 0 { - return format!("Vertex buffer binding {}", binding_num).into(); - } - num -= 1; - } - - if num == 0 { - return "indirect buffer".into(); - } - - panic!() - } - - fn image(&self, mut num: usize) -> &dyn ImageAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(img) = set.image(num) { - return img.0.image(); - } - num -= set.num_images(); - } - panic!() - } - - fn image_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(img) = set.image(num) { - return format!("Image bound to set {} descriptor {}", set_num, img.1) - .into(); - } - num -= set.num_images(); - } - panic!() - } - } - - let pipeline = self - .bindings - .pipeline_graphics - .as_ref() - .unwrap() - .bound_pipeline_graphics(); - - let mut resources = Vec::new(); - let descriptor_sets = self.add_descriptor_set_resources( - &mut resources, - pipeline.layout(), - PipelineBindPoint::Graphics, - ); - let vertex_buffers = - self.add_vertex_buffer_resources(&mut resources, pipeline.vertex_input()); - self.add_indirect_buffer_resources(&mut resources); - - self.append_command( - Cmd { - descriptor_sets, - vertex_buffers, - indirect_buffer, - draw_count, - stride, - }, - &resources, - )?; - - Ok(()) - } - - /// Calls `vkCmdDrawIndexedIndirect` on the builder. - #[inline] - pub unsafe fn draw_indexed_indirect<B>( - &mut self, - indirect_buffer: B, - draw_count: u32, - stride: u32, - ) -> Result<(), SyncCommandBufferBuilderError> - where - B: BufferAccess + Send + Sync + 'static, - { - struct Cmd<B> { - descriptor_sets: SmallVec<[Arc<dyn Command + Send + Sync>; 12]>, - vertex_buffers: SmallVec<[(u32, Arc<dyn Command + Send + Sync>); 4]>, - index_buffer: Arc<dyn Command + Send + Sync>, - indirect_buffer: B, - draw_count: u32, - stride: u32, - } - - impl<B> Command for Cmd<B> - where - B: BufferAccess + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdDrawIndexedIndirect" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.draw_indexed_indirect(&self.indirect_buffer, self.draw_count, self.stride); - } - - fn buffer(&self, mut num: usize) -> &dyn BufferAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(buf) = set.buffer(num) { - return buf.0; - } - num -= set.num_buffers(); - } - - for buffer in self - .vertex_buffers - .iter() - .map(|(binding_num, cmd)| cmd.bound_vertex_buffer(*binding_num)) - { - if num == 0 { - return buffer; - } - num -= 1; - } - - if num == 0 { - return self.index_buffer.bound_index_buffer(); - } else if num == 1 { - return &self.indirect_buffer; - } - - panic!() - } - - fn buffer_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(buf) = set.buffer(num) { - return format!("Buffer bound to set {} descriptor {}", set_num, buf.1) - .into(); - } - num -= set.num_buffers(); - } - - for binding_num in self - .vertex_buffers - .iter() - .map(|(binding_num, _)| *binding_num) - { - if num == 0 { - return format!("Vertex buffer binding {}", binding_num).into(); - } - num -= 1; - } - - if num == 0 { - return "index buffer".into(); - } else if num == 1 { - return "indirect buffer".into(); - } - - panic!() - } - - fn image(&self, mut num: usize) -> &dyn ImageAccess { - for set in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - if let Some(img) = set.image(num) { - return img.0.image(); - } - num -= set.num_images(); - } - panic!() - } - - fn image_name(&self, mut num: usize) -> Cow<'static, str> { - for (set_num, set) in self - .descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| (set_num, cmd.bound_descriptor_set(set_num as u32).0)) - { - if let Some(img) = set.image(num) { - return format!("Image bound to set {} descriptor {}", set_num, img.1) - .into(); - } - num -= set.num_images(); - } - panic!() - } - } - - let pipeline = self - .bindings - .pipeline_graphics - .as_ref() - .unwrap() - .bound_pipeline_graphics(); - - let mut resources = Vec::new(); - let descriptor_sets = self.add_descriptor_set_resources( - &mut resources, - pipeline.layout(), - PipelineBindPoint::Graphics, - ); - let vertex_buffers = - self.add_vertex_buffer_resources(&mut resources, pipeline.vertex_input()); - let index_buffer = self.add_index_buffer_resources(&mut resources); - self.add_indirect_buffer_resources(&mut resources); - - self.append_command( - Cmd { - descriptor_sets, - vertex_buffers, - index_buffer, - indirect_buffer, - draw_count, - stride, - }, - &resources, - )?; - - Ok(()) - } - - /// Calls `vkCmdEndQuery` on the builder. - #[inline] - pub unsafe fn end_query(&mut self, query_pool: Arc<QueryPool>, query: u32) { - struct Cmd { - query_pool: Arc<QueryPool>, - query: u32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdEndQuery" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.end_query(self.query_pool.query(self.query).unwrap()); - } - } - - self.append_command(Cmd { query_pool, query }, &[]).unwrap(); - } - - /// Calls `vkCmdEndRenderPass` on the builder. - #[inline] - pub unsafe fn end_render_pass(&mut self) { - struct Cmd; - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdEndRenderPass" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.end_render_pass(); - } - } - - self.append_command(Cmd, &[]).unwrap(); - debug_assert!(self.latest_render_pass_enter.is_some()); - self.latest_render_pass_enter = None; - } - - /// Starts the process of executing secondary command buffers. Returns an intermediate struct - /// which can be used to add the command buffers. - #[inline] - pub unsafe fn execute_commands(&mut self) -> SyncCommandBufferBuilderExecuteCommands { - SyncCommandBufferBuilderExecuteCommands { - builder: self, - inner: Vec::new(), - } - } - - /// Calls `vkCmdFillBuffer` on the builder. - #[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<B> Command for Cmd<B> - where - B: BufferAccess + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdFillBuffer" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.fill_buffer(&self.buffer, self.data); - } - - 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 }, - &[( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - )], - ) - .unwrap(); - } - - /// Calls `vkCmdNextSubpass` on the builder. - #[inline] - pub unsafe fn next_subpass(&mut self, subpass_contents: SubpassContents) { - struct Cmd { - subpass_contents: SubpassContents, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdNextSubpass" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.next_subpass(self.subpass_contents); - } - } - - self.append_command(Cmd { subpass_contents }, &[]).unwrap(); - } - - /// Calls `vkCmdPushConstants` on the builder. - #[inline] - pub unsafe fn push_constants<D>( - &mut self, - pipeline_layout: Arc<PipelineLayout>, - stages: ShaderStages, - offset: u32, - size: u32, - data: &D, - ) where - D: ?Sized + Send + Sync + 'static, - { - struct Cmd { - pipeline_layout: Arc<PipelineLayout>, - stages: ShaderStages, - offset: u32, - size: u32, - data: Box<[u8]>, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdPushConstants" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.push_constants::<[u8]>( - &self.pipeline_layout, - self.stages, - self.offset, - self.size, - &self.data, - ); - } - } - - 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(), - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdResetEvent` on the builder. - #[inline] - pub unsafe fn reset_event(&mut self, event: Arc<Event>, stages: PipelineStages) { - struct Cmd { - event: Arc<Event>, - stages: PipelineStages, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdResetEvent" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.reset_event(&self.event, self.stages); - } - } - - self.append_command(Cmd { event, stages }, &[]).unwrap(); - } - - /// Calls `vkCmdResetQueryPool` on the builder. - #[inline] - pub unsafe fn reset_query_pool(&mut self, query_pool: Arc<QueryPool>, queries: Range<u32>) { - struct Cmd { - query_pool: Arc<QueryPool>, - queries: Range<u32>, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdResetQueryPool" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.reset_query_pool(self.query_pool.queries_range(self.queries.clone()).unwrap()); - } - } - - self.append_command( - Cmd { - query_pool, - queries, - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdSetBlendConstants` on the builder. - #[inline] - pub unsafe fn set_blend_constants(&mut self, constants: [f32; 4]) { - struct Cmd { - constants: [f32; 4], - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetBlendConstants" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_blend_constants(self.constants); - } - } - - self.append_command(Cmd { constants }, &[]).unwrap(); - } - - /// Calls `vkCmdSetDepthBias` on the builder. - #[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 Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetDepthBias" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_depth_bias(self.constant_factor, self.clamp, self.slope_factor); - } - } - - self.append_command( - Cmd { - constant_factor, - clamp, - slope_factor, - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdSetDepthBounds` on the builder. - #[inline] - pub unsafe fn set_depth_bounds(&mut self, min: f32, max: f32) { - struct Cmd { - min: f32, - max: f32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetDepthBounds" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_depth_bounds(self.min, self.max); - } - } - - self.append_command(Cmd { min, max }, &[]).unwrap(); - } - - /// Calls `vkCmdSetEvent` on the builder. - #[inline] - pub unsafe fn set_event(&mut self, event: Arc<Event>, stages: PipelineStages) { - struct Cmd { - event: Arc<Event>, - stages: PipelineStages, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetEvent" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_event(&self.event, self.stages); - } - } - - self.append_command(Cmd { event, stages }, &[]).unwrap(); - } - - /// Calls `vkCmdSetLineWidth` on the builder. - #[inline] - pub unsafe fn set_line_width(&mut self, line_width: f32) { - struct Cmd { - line_width: f32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetLineWidth" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_line_width(self.line_width); - } - } - - self.append_command(Cmd { line_width }, &[]).unwrap(); - } - - /// Calls `vkCmdSetStencilCompareMask` on the builder. - #[inline] - pub unsafe fn set_stencil_compare_mask(&mut self, face_mask: StencilFaces, compare_mask: u32) { - struct Cmd { - face_mask: StencilFaces, - compare_mask: u32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetStencilCompareMask" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_stencil_compare_mask(self.face_mask, self.compare_mask); - } - } - - self.append_command( - Cmd { - face_mask, - compare_mask, - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdSetStencilReference` on the builder. - #[inline] - pub unsafe fn set_stencil_reference(&mut self, face_mask: StencilFaces, reference: u32) { - struct Cmd { - face_mask: StencilFaces, - reference: u32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetStencilReference" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_stencil_reference(self.face_mask, self.reference); - } - } - - self.append_command( - Cmd { - face_mask, - reference, - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdSetStencilWriteMask` on the builder. - #[inline] - pub unsafe fn set_stencil_write_mask(&mut self, face_mask: StencilFaces, write_mask: u32) { - struct Cmd { - face_mask: StencilFaces, - write_mask: u32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdSetStencilWriteMask" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_stencil_write_mask(self.face_mask, self.write_mask); - } - } - - self.append_command( - Cmd { - face_mask, - write_mask, - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdSetScissor` on the builder. - /// - /// If the list is empty then the command is automatically ignored. - #[inline] - pub unsafe fn set_scissor<I>(&mut self, first_scissor: u32, scissors: I) - where - I: IntoIterator<Item = Scissor> + Send + Sync + 'static, - { - struct Cmd<I> { - first_scissor: u32, - scissors: Mutex<Option<I>>, - } - - impl<I> Command for Cmd<I> - where - I: IntoIterator<Item = Scissor>, - { - fn name(&self) -> &'static str { - "vkCmdSetScissor" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_scissor( - self.first_scissor, - self.scissors.lock().unwrap().take().unwrap(), - ); - } - } - - self.append_command( - Cmd { - first_scissor, - scissors: Mutex::new(Some(scissors)), - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdSetViewport` on the builder. - /// - /// If the list is empty then the command is automatically ignored. - #[inline] - pub unsafe fn set_viewport<I>(&mut self, first_viewport: u32, viewports: I) - where - I: IntoIterator<Item = Viewport> + Send + Sync + 'static, - { - struct Cmd<I> { - first_viewport: u32, - viewports: Mutex<Option<I>>, - } - - impl<I> Command for Cmd<I> - where - I: IntoIterator<Item = Viewport>, - { - fn name(&self) -> &'static str { - "vkCmdSetViewport" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.set_viewport( - self.first_viewport, - self.viewports.lock().unwrap().take().unwrap(), - ); - } - } - - self.append_command( - Cmd { - first_viewport, - viewports: Mutex::new(Some(viewports)), - }, - &[], - ) - .unwrap(); - } - - /// Calls `vkCmdUpdateBuffer` on the builder. - #[inline] - pub unsafe fn update_buffer<B, D, Dd>(&mut self, buffer: B, data: Dd) - where - B: BufferAccess + Send + Sync + 'static, - D: ?Sized, - Dd: SafeDeref<Target = D> + Send + Sync + 'static, - { - struct Cmd<B, Dd> { - buffer: B, - data: Dd, - } - - impl<B, D, Dd> Command for Cmd<B, Dd> - where - B: BufferAccess + Send + Sync + 'static, - D: ?Sized, - Dd: SafeDeref<Target = D> + Send + Sync + 'static, - { - fn name(&self) -> &'static str { - "vkCmdUpdateBuffer" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.update_buffer(&self.buffer, self.data.deref()); - } - - 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 }, - &[( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - transfer: true, - ..PipelineStages::none() - }, - access: AccessFlags { - transfer_write: true, - ..AccessFlags::none() - }, - exclusive: true, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - )], - ) - .unwrap(); - } - - /// Calls `vkCmdWriteTimestamp` on the builder. - #[inline] - pub unsafe fn write_timestamp( - &mut self, - query_pool: Arc<QueryPool>, - query: u32, - stage: PipelineStage, - ) { - struct Cmd { - query_pool: Arc<QueryPool>, - query: u32, - stage: PipelineStage, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdWriteTimestamp" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.write_timestamp(self.query_pool.query(self.query).unwrap(), self.stage); - } - } - - self.append_command( - Cmd { - query_pool, - query, - stage, - }, - &[], - ) - .unwrap(); - } - - fn add_descriptor_set_resources( - &self, - resources: &mut Vec<( - KeyTy, - Option<( - PipelineMemoryAccess, - ImageLayout, - ImageLayout, - ImageUninitializedSafe, - )>, - )>, - pipeline_layout: &PipelineLayout, - pipeline_bind_point: PipelineBindPoint, - ) -> SmallVec<[Arc<dyn Command + Send + Sync>; 12]> { - let descriptor_sets: SmallVec<[Arc<dyn Command + Send + Sync>; 12]> = (0..pipeline_layout - .descriptor_set_layouts() - .len() - as u32) - .map(|set_num| self.bindings.descriptor_sets[&pipeline_bind_point][&set_num].clone()) - .collect(); - - for ds in descriptor_sets - .iter() - .enumerate() - .map(|(set_num, cmd)| cmd.bound_descriptor_set(set_num as u32).0) - { - for buf_num in 0..ds.num_buffers() { - let desc = ds - .layout() - .descriptor(ds.buffer(buf_num).unwrap().1 as usize) - .unwrap(); - let exclusive = !desc.readonly; - let (stages, access) = desc.pipeline_stages_and_access(); - resources.push(( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages, - access, - exclusive, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - )); - } - for img_num in 0..ds.num_images() { - let (image_view, desc_num) = ds.image(img_num).unwrap(); - let desc = ds.layout().descriptor(desc_num as usize).unwrap(); - let exclusive = !desc.readonly; - let (stages, access) = desc.pipeline_stages_and_access(); - let mut ignore_me_hack = false; - let layouts = image_view - .image() - .descriptor_layouts() - .expect("descriptor_layouts must return Some when used in an image view"); - let layout = match desc.ty { - DescriptorDescTy::CombinedImageSampler(_) => layouts.combined_image_sampler, - DescriptorDescTy::Image(ref img) => { - if img.sampled { - layouts.sampled_image - } else { - layouts.storage_image - } - } - DescriptorDescTy::InputAttachment { .. } => { - // FIXME: This is tricky. Since we read from the input attachment - // and this input attachment is being written in an earlier pass, - // vulkano will think that it needs to put a pipeline barrier and will - // return a `Conflict` error. For now as a work-around we simply ignore - // input attachments. - ignore_me_hack = true; - layouts.input_attachment - } - _ => panic!("Tried to bind an image to a non-image descriptor"), - }; - resources.push(( - KeyTy::Image, - if ignore_me_hack { - None - } else { - Some(( - PipelineMemoryAccess { - stages, - access, - exclusive, - }, - layout, - layout, - ImageUninitializedSafe::Unsafe, - )) - }, - )); - } - } - - descriptor_sets - } - - fn add_vertex_buffer_resources( - &self, - resources: &mut Vec<( - KeyTy, - Option<( - PipelineMemoryAccess, - ImageLayout, - ImageLayout, - ImageUninitializedSafe, - )>, - )>, - vertex_input: &VertexInput, - ) -> SmallVec<[(u32, Arc<dyn Command + Send + Sync>); 4]> { - let vertex_buffers: SmallVec<[(u32, Arc<dyn Command + Send + Sync>); 4]> = vertex_input - .bindings() - .map(|(binding_num, _)| { - ( - binding_num, - self.bindings.vertex_buffers[&binding_num].clone(), - ) - }) - .collect(); - - resources.extend(vertex_buffers.iter().map(|_| { - ( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - vertex_input: true, - ..PipelineStages::none() - }, - access: AccessFlags { - vertex_attribute_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - ) - })); - - vertex_buffers - } - - fn add_index_buffer_resources( - &self, - resources: &mut Vec<( - KeyTy, - Option<( - PipelineMemoryAccess, - ImageLayout, - ImageLayout, - ImageUninitializedSafe, - )>, - )>, - ) -> Arc<dyn Command + Send + Sync> { - let index_buffer = self.bindings.index_buffer.as_ref().unwrap().clone(); - - resources.push(( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - vertex_input: true, - ..PipelineStages::none() - }, - access: AccessFlags { - index_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - )); - - index_buffer - } - - fn add_indirect_buffer_resources( - &self, - resources: &mut Vec<( - KeyTy, - Option<( - PipelineMemoryAccess, - ImageLayout, - ImageLayout, - ImageUninitializedSafe, - )>, - )>, - ) { - resources.push(( - KeyTy::Buffer, - Some(( - PipelineMemoryAccess { - stages: PipelineStages { - draw_indirect: true, - ..PipelineStages::none() - }, // TODO: is draw_indirect correct for dispatch too? - access: AccessFlags { - indirect_command_read: true, - ..AccessFlags::none() - }, - exclusive: false, - }, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - )); - } -} - -pub struct SyncCommandBufferBuilderBindDescriptorSets<'b> { - builder: &'b mut SyncCommandBufferBuilder, - descriptor_sets: SmallVec<[DescriptorSetWithOffsets; 12]>, -} - -impl<'b> SyncCommandBufferBuilderBindDescriptorSets<'b> { - /// Adds a descriptor set to the list. - #[inline] - pub fn add<S>(&mut self, descriptor_set: S) - where - S: Into<DescriptorSetWithOffsets>, - { - self.descriptor_sets.push(descriptor_set.into()); - } - - #[inline] - pub unsafe fn submit( - self, - pipeline_bind_point: PipelineBindPoint, - pipeline_layout: Arc<PipelineLayout>, - first_binding: u32, - ) -> Result<(), SyncCommandBufferBuilderError> { - if self.descriptor_sets.is_empty() { - return Ok(()); - } - - struct Cmd { - descriptor_sets: SmallVec<[DescriptorSetWithOffsets; 12]>, - pipeline_bind_point: PipelineBindPoint, - pipeline_layout: Arc<PipelineLayout>, - first_binding: u32, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdBindDescriptorSets" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - let descriptor_sets = self.descriptor_sets.iter().map(|x| x.as_ref().0.inner()); - let dynamic_offsets = self - .descriptor_sets - .iter() - .map(|x| x.as_ref().1.iter().copied()) - .flatten(); - - out.bind_descriptor_sets( - self.pipeline_bind_point, - &self.pipeline_layout, - self.first_binding, - descriptor_sets, - dynamic_offsets, - ); - } - - fn bound_descriptor_set(&self, set_num: u32) -> (&dyn DescriptorSet, &[u32]) { - let index = set_num.checked_sub(self.first_binding).unwrap() as usize; - self.descriptor_sets[index].as_ref() - } - } - - let num_descriptor_sets = self.descriptor_sets.len() as u32; - self.builder.append_command( - Cmd { - descriptor_sets: self.descriptor_sets, - pipeline_bind_point, - pipeline_layout, - first_binding, - }, - &[], - )?; - - let cmd = self.builder.commands.last().unwrap(); - let sets = self - .builder - .bindings - .descriptor_sets - .entry(pipeline_bind_point) - .or_default(); - sets.retain(|&set_num, _| set_num < first_binding); // Remove all descriptor sets with a higher number - - for i in 0..num_descriptor_sets { - sets.insert(first_binding + i, cmd.clone()); - } - - Ok(()) - } -} - -/// Prototype for a `vkCmdBindVertexBuffers`. -pub struct SyncCommandBufferBuilderBindVertexBuffer<'a> { - builder: &'a mut SyncCommandBufferBuilder, - inner: UnsafeCommandBufferBuilderBindVertexBuffer, - buffers: SmallVec<[Box<dyn BufferAccess + Send + Sync>; 4]>, -} - -impl<'a> SyncCommandBufferBuilderBindVertexBuffer<'a> { - /// Adds a buffer to the list. - #[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: Mutex<Option<UnsafeCommandBufferBuilderBindVertexBuffer>>, - buffers: SmallVec<[Box<dyn BufferAccess + Send + Sync>; 4]>, - } - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdBindVertexBuffers" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - out.bind_vertex_buffers( - self.first_binding, - self.inner.lock().unwrap().take().unwrap(), - ); - } - - fn bound_vertex_buffer(&self, binding_num: u32) -> &dyn BufferAccess { - let index = binding_num.checked_sub(self.first_binding).unwrap() as usize; - &self.buffers[index] - } - } - - let num_buffers = self.buffers.len() as u32; - self.builder.append_command( - Cmd { - first_binding, - inner: Mutex::new(Some(self.inner)), - buffers: self.buffers, - }, - &[], - )?; - - let cmd = self.builder.commands.last().unwrap(); - for i in 0..num_buffers { - self.builder - .bindings - .vertex_buffers - .insert(first_binding + i, cmd.clone()); - } - - Ok(()) - } -} - -/// Prototype for a `vkCmdExecuteCommands`. -pub struct SyncCommandBufferBuilderExecuteCommands<'a> { - builder: &'a mut SyncCommandBufferBuilder, - inner: Vec<Box<dyn SecondaryCommandBuffer + Send + Sync>>, -} - -impl<'a> SyncCommandBufferBuilderExecuteCommands<'a> { - /// Adds a command buffer to the list. - #[inline] - pub fn add<C>(&mut self, command_buffer: C) - where - C: SecondaryCommandBuffer + Send + Sync + 'static, - { - self.inner.push(Box::new(command_buffer)); - } - - #[inline] - pub unsafe fn submit(self) -> Result<(), SyncCommandBufferBuilderError> { - struct DropUnlock(Box<dyn SecondaryCommandBuffer + Send + Sync>); - impl std::ops::Deref for DropUnlock { - type Target = Box<dyn SecondaryCommandBuffer + Send + Sync>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - unsafe impl SafeDeref for DropUnlock {} - - impl Drop for DropUnlock { - fn drop(&mut self) { - unsafe { - self.unlock(); - } - } - } - - struct Cmd(Vec<DropUnlock>); - - impl Command for Cmd { - fn name(&self) -> &'static str { - "vkCmdExecuteCommands" - } - - unsafe fn send(&self, out: &mut UnsafeCommandBufferBuilder) { - let mut execute = UnsafeCommandBufferBuilderExecuteCommands::new(); - self.0 - .iter() - .for_each(|cbuf| execute.add_raw(cbuf.inner().internal_object())); - out.execute_commands(execute); - } - - fn buffer(&self, mut num: usize) -> &dyn BufferAccess { - for cbuf in self.0.iter() { - if let Some(buf) = cbuf.buffer(num) { - return buf.0; - } - num -= cbuf.num_buffers(); - } - panic!() - } - - fn buffer_name(&self, mut num: usize) -> Cow<'static, str> { - for (cbuf_num, cbuf) in self.0.iter().enumerate() { - if let Some(buf) = cbuf.buffer(num) { - return format!("Buffer bound to secondary command buffer {}", cbuf_num) - .into(); - } - num -= cbuf.num_buffers(); - } - panic!() - } - - fn image(&self, mut num: usize) -> &dyn ImageAccess { - for cbuf in self.0.iter() { - if let Some(img) = cbuf.image(num) { - return img.0; - } - num -= cbuf.num_images(); - } - panic!() - } - - fn image_name(&self, mut num: usize) -> Cow<'static, str> { - for (cbuf_num, cbuf) in self.0.iter().enumerate() { - if let Some(img) = cbuf.image(num) { - return format!("Image bound to secondary command buffer {}", cbuf_num) - .into(); - } - num -= cbuf.num_images(); - } - panic!() - } - } - - let resources = { - let mut resources = Vec::new(); - for cbuf in self.inner.iter() { - for buf_num in 0..cbuf.num_buffers() { - resources.push(( - KeyTy::Buffer, - Some(( - cbuf.buffer(buf_num).unwrap().1, - ImageLayout::Undefined, - ImageLayout::Undefined, - ImageUninitializedSafe::Unsafe, - )), - )); - } - for img_num in 0..cbuf.num_images() { - let (_, memory, start_layout, end_layout, image_uninitialized_safe) = - cbuf.image(img_num).unwrap(); - resources.push(( - KeyTy::Image, - Some((memory, start_layout, end_layout, image_uninitialized_safe)), - )); - } - } - resources - }; - - self.builder.append_command( - Cmd(self - .inner - .into_iter() - .map(|cbuf| { - cbuf.lock_record()?; - Ok(DropUnlock(cbuf)) - }) - .collect::<Result<Vec<_>, CommandBufferExecError>>()?), - &resources, - )?; - - Ok(()) - } -} |