Command buffer allocator API 2.0 (#2403)

* Make `CommandBufferAllocator` object-safe, remove the generics

* Fix tests

* Fix examples

* Remove the panic

* Remove outdated docs

* Document `Send + Sync` impl of `UnsafeCommandBuffer`
This commit is contained in:
marc0246 2023-11-14 17:57:43 +01:00 committed by GitHub
parent 4d56fc38de
commit 43e2db0dbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 836 additions and 947 deletions

View File

@ -333,7 +333,7 @@ fn main() -> Result<(), impl Error> {
// Initialize the textures. // Initialize the textures.
{ {
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
command_buffer_allocator.as_ref(), command_buffer_allocator.clone(),
graphics_queue.queue_family_index(), graphics_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -589,7 +589,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
command_buffer_allocator.as_ref(), command_buffer_allocator.clone(),
graphics_queue.queue_family_index(), graphics_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -763,7 +763,7 @@ fn run_worker(
let texture = textures[!current_index as usize].clone(); let texture = textures[!current_index as usize].clone();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
command_buffer_allocator.as_ref(), command_buffer_allocator.clone(),
transfer_queue.queue_family_index(), transfer_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -155,8 +155,10 @@ fn main() {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
// We start by creating the buffer that will store the data. // We start by creating the buffer that will store the data.
let data_buffer = Buffer::from_iter( let data_buffer = Buffer::from_iter(
@ -194,7 +196,7 @@ fn main() {
// In order to execute our operation, we have to build a command buffer. // In order to execute our operation, we have to build a command buffer.
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -269,8 +269,10 @@ fn main() -> Result<(), impl Error> {
let mut recreate_swapchain = false; let mut recreate_swapchain = false;
let mut previous_frame_end = Some(sync::now(device.clone()).boxed()); let mut previous_frame_end = Some(sync::now(device.clone()).boxed());
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
event_loop.run(move |event, elwt| { event_loop.run(move |event, elwt| {
elwt.set_control_flow(ControlFlow::Poll); elwt.set_control_flow(ControlFlow::Poll);
@ -368,7 +370,7 @@ fn main() -> Result<(), impl Error> {
buffer.write().unwrap().copy_from_slice(&data); buffer.write().unwrap().copy_from_slice(&data);
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -138,8 +138,10 @@ fn main() -> Result<(), impl Error> {
) )
.unwrap(); .unwrap();
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut width = swapchain.image_extent()[0]; let mut width = swapchain.image_extent()[0];
let mut height = swapchain.image_extent()[1]; let mut height = swapchain.image_extent()[1];
@ -206,7 +208,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -183,7 +183,7 @@ impl AmbientLightingSystem {
}; };
let mut builder = AutoCommandBufferBuilder::secondary( let mut builder = AutoCommandBufferBuilder::secondary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
CommandBufferInheritanceInfo { CommandBufferInheritanceInfo {

View File

@ -197,7 +197,7 @@ impl DirectionalLightingSystem {
}; };
let mut builder = AutoCommandBufferBuilder::secondary( let mut builder = AutoCommandBufferBuilder::secondary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
CommandBufferInheritanceInfo { CommandBufferInheritanceInfo {

View File

@ -210,7 +210,7 @@ impl PointLightingSystem {
}; };
let mut builder = AutoCommandBufferBuilder::secondary( let mut builder = AutoCommandBufferBuilder::secondary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
CommandBufferInheritanceInfo { CommandBufferInheritanceInfo {

View File

@ -339,7 +339,7 @@ impl FrameSystem {
// Start the command buffer builder that will be filled throughout the frame handling. // Start the command buffer builder that will be filled throughout the frame handling.
let mut command_buffer_builder = AutoCommandBufferBuilder::primary( let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -129,7 +129,7 @@ impl TriangleDrawSystem {
/// Builds a secondary command buffer that draws the triangle on the current subpass. /// Builds a secondary command buffer that draws the triangle on the current subpass.
pub fn draw(&self, viewport_dimensions: [u32; 2]) -> Arc<SecondaryAutoCommandBuffer> { pub fn draw(&self, viewport_dimensions: [u32; 2]) -> Arc<SecondaryAutoCommandBuffer> {
let mut builder = AutoCommandBufferBuilder::secondary( let mut builder = AutoCommandBufferBuilder::secondary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
CommandBufferInheritanceInfo { CommandBufferInheritanceInfo {

View File

@ -149,8 +149,10 @@ fn main() {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
// Create the input buffer. Data in a dynamic buffer **MUST** be aligned to // Create the input buffer. Data in a dynamic buffer **MUST** be aligned to
// `min_uniform_buffer_offset_align` or `min_storage_buffer_offset_align`, depending on the // `min_uniform_buffer_offset_align` or `min_storage_buffer_offset_align`, depending on the
@ -235,7 +237,7 @@ fn main() {
// Build the command buffer, using different offsets for each call. // Build the command buffer, using different offsets for each call.
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -206,8 +206,10 @@ fn main() {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let image = Image::new( let image = Image::new(
memory_allocator.clone(), memory_allocator.clone(),
@ -248,7 +250,7 @@ fn main() {
.unwrap(); .unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -273,8 +273,10 @@ mod linux {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let layout = pipeline.layout().set_layouts().get(0).unwrap(); let layout = pipeline.layout().set_layouts().get(0).unwrap();
@ -388,7 +390,7 @@ mod linux {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -205,10 +205,13 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut uploads = AutoCommandBufferBuilder::primary( let mut uploads = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -468,7 +471,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -205,10 +205,13 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut uploads = AutoCommandBufferBuilder::primary( let mut uploads = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -416,7 +419,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -211,10 +211,13 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut uploads = AutoCommandBufferBuilder::primary( let mut uploads = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -434,7 +437,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -365,8 +365,10 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
event_loop.run(move |event, elwt| { event_loop.run(move |event, elwt| {
elwt.set_control_flow(ControlFlow::Poll); elwt.set_control_flow(ControlFlow::Poll);
@ -466,7 +468,7 @@ fn main() -> Result<(), impl Error> {
.unwrap(); .unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -338,8 +338,10 @@ fn main() -> Result<(), impl Error> {
let mut recreate_swapchain = false; let mut recreate_swapchain = false;
let mut previous_frame_end = Some(sync::now(device.clone()).boxed()); let mut previous_frame_end = Some(sync::now(device.clone()).boxed());
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
event_loop.run(move |event, elwt| { event_loop.run(move |event, elwt| {
elwt.set_control_flow(ControlFlow::Poll); elwt.set_control_flow(ControlFlow::Poll);
@ -401,7 +403,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -149,7 +149,7 @@ impl FractalComputePipeline {
) )
.unwrap(); .unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.queue.queue_family_index(), self.queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -205,7 +205,7 @@ impl PixelsDrawPipeline {
image: Arc<ImageView>, image: Arc<ImageView>,
) -> Arc<SecondaryAutoCommandBuffer> { ) -> Arc<SecondaryAutoCommandBuffer> {
let mut builder = AutoCommandBufferBuilder::secondary( let mut builder = AutoCommandBufferBuilder::secondary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
CommandBufferInheritanceInfo { CommandBufferInheritanceInfo {

View File

@ -89,7 +89,7 @@ impl RenderPassPlaceOverFrame {
// Create primary command buffer builder. // Create primary command buffer builder.
let mut command_buffer_builder = AutoCommandBufferBuilder::primary( let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -360,7 +360,10 @@ fn main() {
depth_range: 0.0..=1.0, depth_range: 0.0..=1.0,
}; };
let command_buffer_allocator = StandardCommandBufferAllocator::new(device, Default::default()); let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
device,
Default::default(),
));
let buf = Buffer::from_iter( let buf = Buffer::from_iter(
memory_allocator, memory_allocator,
@ -378,7 +381,7 @@ fn main() {
.unwrap(); .unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -131,7 +131,7 @@ impl GameOfLifeComputePipeline {
dead_color: [f32; 4], dead_color: [f32; 4],
) -> Box<dyn GpuFuture> { ) -> Box<dyn GpuFuture> {
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.compute_queue.queue_family_index(), self.compute_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -201,7 +201,7 @@ impl PixelsDrawPipeline {
image: Arc<ImageView>, image: Arc<ImageView>,
) -> Arc<SecondaryAutoCommandBuffer> { ) -> Arc<SecondaryAutoCommandBuffer> {
let mut builder = AutoCommandBufferBuilder::secondary( let mut builder = AutoCommandBufferBuilder::secondary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
CommandBufferInheritanceInfo { CommandBufferInheritanceInfo {

View File

@ -79,7 +79,7 @@ impl RenderPassPlaceOverFrame {
// Create a primary command buffer builder. // Create a primary command buffer builder.
let mut command_buffer_builder = AutoCommandBufferBuilder::primary( let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.as_ref(), self.command_buffer_allocator.clone(),
self.gfx_queue.queue_family_index(), self.gfx_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -303,8 +303,10 @@ fn main() -> Result<(), impl Error> {
depth_range: 0.0..=1.0, depth_range: 0.0..=1.0,
}; };
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
window_surfaces.insert( window_surfaces.insert(
window_id, window_id,
@ -446,7 +448,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -305,8 +305,10 @@ fn main() {
.unwrap() .unwrap()
}; };
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let create_buffer = || { let create_buffer = || {
Buffer::from_iter( Buffer::from_iter(
@ -329,7 +331,7 @@ fn main() {
let buffer2 = create_buffer(); let buffer2 = create_buffer();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -351,8 +351,10 @@ fn main() -> Result<(), impl Error> {
depth_range: 0.0..=1.0, depth_range: 0.0..=1.0,
}; };
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut framebuffers = window_size_dependent_setup( let mut framebuffers = window_size_dependent_setup(
&images, &images,
@ -425,7 +427,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -137,8 +137,10 @@ fn main() {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let data_buffer = Buffer::from_iter( let data_buffer = Buffer::from_iter(
memory_allocator, memory_allocator,
@ -179,7 +181,7 @@ fn main() {
// Note that there is no type safety for the push constant data, so be careful to only pass an // Note that there is no type safety for the push constant data, so be careful to only pass an
// instance of the struct generated by the `vulkano_shaders::shaders!` macro. // instance of the struct generated by the `vulkano_shaders::shaders!` macro.
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -197,10 +197,12 @@ fn main() -> Result<(), impl Error> {
) )
.unwrap(); .unwrap();
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut uploads = AutoCommandBufferBuilder::primary( let mut uploads = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -404,7 +406,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -265,10 +265,13 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut uploads = AutoCommandBufferBuilder::primary( let mut uploads = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -537,7 +540,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -284,8 +284,10 @@ fn main() -> Result<(), impl Error> {
let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut viewport); let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut viewport);
let mut previous_frame_end = Some(sync::now(device.clone()).boxed()); let mut previous_frame_end = Some(sync::now(device.clone()).boxed());
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
event_loop.run(move |event, elwt| { event_loop.run(move |event, elwt| {
elwt.set_control_flow(ControlFlow::Poll); elwt.set_control_flow(ControlFlow::Poll);
@ -347,7 +349,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
) )

View File

@ -129,8 +129,10 @@ fn main() {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let data_buffer = Buffer::from_iter( let data_buffer = Buffer::from_iter(
memory_allocator, memory_allocator,
@ -161,7 +163,7 @@ fn main() {
.unwrap(); .unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -137,8 +137,10 @@ fn main() {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let data_buffer = Buffer::from_iter( let data_buffer = Buffer::from_iter(
memory_allocator, memory_allocator,
@ -165,7 +167,7 @@ fn main() {
.unwrap(); .unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -180,8 +180,8 @@ fn main() {
queue: Arc<Queue>, queue: Arc<Queue>,
data_buffer: Subbuffer<[u32]>, data_buffer: Subbuffer<[u32]>,
parameters: shaders::Parameters, parameters: shaders::Parameters,
command_buffer_allocator: &StandardCommandBufferAllocator,
descriptor_set_allocator: Arc<StandardDescriptorSetAllocator>, descriptor_set_allocator: Arc<StandardDescriptorSetAllocator>,
command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
) { ) {
let layout = pipeline.layout().set_layouts().get(0).unwrap(); let layout = pipeline.layout().set_layouts().get(0).unwrap();
let set = DescriptorSet::new( let set = DescriptorSet::new(
@ -224,12 +224,14 @@ fn main() {
} }
let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone()));
let command_buffer_allocator =
StandardCommandBufferAllocator::new(device.clone(), Default::default());
let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new(
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
device.clone(),
Default::default(),
));
// Prepare test array `[0, 1, 2, 3....]`. // Prepare test array `[0, 1, 2, 3....]`.
let data_buffer = Buffer::from_iter( let data_buffer = Buffer::from_iter(
@ -301,8 +303,8 @@ fn main() {
queue.clone(), queue.clone(),
data_buffer.clone(), data_buffer.clone(),
shaders::Parameters { value: 2 }, shaders::Parameters { value: 2 },
&command_buffer_allocator,
descriptor_set_allocator.clone(), descriptor_set_allocator.clone(),
command_buffer_allocator.clone(),
); );
// Then add 1 to each value. // Then add 1 to each value.
@ -311,8 +313,8 @@ fn main() {
queue.clone(), queue.clone(),
data_buffer.clone(), data_buffer.clone(),
shaders::Parameters { value: 1 }, shaders::Parameters { value: 1 },
&command_buffer_allocator,
descriptor_set_allocator.clone(), descriptor_set_allocator.clone(),
command_buffer_allocator.clone(),
); );
// Then multiply each value by 3. // Then multiply each value by 3.
@ -321,8 +323,8 @@ fn main() {
queue, queue,
data_buffer.clone(), data_buffer.clone(),
shaders::Parameters { value: 3 }, shaders::Parameters { value: 3 },
&command_buffer_allocator,
descriptor_set_allocator, descriptor_set_allocator,
command_buffer_allocator,
); );
let data_buffer_content = data_buffer.read().unwrap(); let data_buffer_content = data_buffer.read().unwrap();

View File

@ -322,8 +322,10 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
#[derive(BufferContents, Vertex)] #[derive(BufferContents, Vertex)]
#[repr(C)] #[repr(C)]
@ -385,7 +387,7 @@ fn main() -> Result<(), impl Error> {
// Create one-time command to copy between the buffers. // Create one-time command to copy between the buffers.
let mut cbb = AutoCommandBufferBuilder::primary( let mut cbb = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -580,7 +582,7 @@ fn main() -> Result<(), impl Error> {
}; };
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -138,8 +138,10 @@ fn main() {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let data_buffer = Buffer::from_iter( let data_buffer = Buffer::from_iter(
memory_allocator, memory_allocator,
@ -166,7 +168,7 @@ fn main() {
.unwrap(); .unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -255,8 +255,10 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
event_loop.run(move |event, elwt| { event_loop.run(move |event, elwt| {
match event { match event {
@ -364,7 +366,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -402,8 +402,10 @@ fn main() -> Result<(), impl Error> {
}; };
let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut viewport); let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut viewport);
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
event_loop.run(move |event, elwt| { event_loop.run(move |event, elwt| {
elwt.set_control_flow(ControlFlow::Poll); elwt.set_control_flow(ControlFlow::Poll);
@ -465,7 +467,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -207,10 +207,13 @@ fn main() -> Result<(), impl Error> {
device.clone(), device.clone(),
Default::default(), Default::default(),
)); ));
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut uploads = AutoCommandBufferBuilder::primary( let mut uploads = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -427,7 +430,7 @@ fn main() -> Result<(), impl Error> {
} }
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -482,8 +482,10 @@ fn main() -> Result<(), impl Error> {
// Before we can start creating and recording command buffers, we need a way of allocating // Before we can start creating and recording command buffers, we need a way of allocating
// them. Vulkano provides a command buffer allocator, which manages raw Vulkan command pools // them. Vulkano provides a command buffer allocator, which manages raw Vulkan command pools
// underneath and provides a safe interface for them. // underneath and provides a safe interface for them.
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
// Initialization is finally finished! // Initialization is finally finished!
@ -596,7 +598,7 @@ fn main() -> Result<(), impl Error> {
// Note that we have to pass a queue family when we create the command buffer. The // Note that we have to pass a queue family when we create the command buffer. The
// command buffer will only be executable on that given queue family. // command buffer will only be executable on that given queue family.
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -479,8 +479,10 @@ fn main() -> Result<(), impl Error> {
// Before we can start creating and recording command buffers, we need a way of allocating // Before we can start creating and recording command buffers, we need a way of allocating
// them. Vulkano provides a command buffer allocator, which manages raw Vulkan command pools // them. Vulkano provides a command buffer allocator, which manages raw Vulkan command pools
// underneath and provides a safe interface for them. // underneath and provides a safe interface for them.
let command_buffer_allocator = let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
// Initialization is finally finished! // Initialization is finally finished!
@ -598,7 +600,7 @@ fn main() -> Result<(), impl Error> {
// Note that we have to pass a queue family when we create the command buffer. The // Note that we have to pass a queue family when we create the command buffer. The
// command buffer will only be executable on that given queue family. // command buffer will only be executable on that given queue family.
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&command_buffer_allocator, command_buffer_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )

View File

@ -87,7 +87,7 @@ const MAX_ARENAS: usize = 32;
/// ///
/// # let queue: std::sync::Arc<vulkano::device::Queue> = return; /// # let queue: std::sync::Arc<vulkano::device::Queue> = return;
/// # let memory_allocator: std::sync::Arc<vulkano::memory::allocator::StandardMemoryAllocator> = return; /// # let memory_allocator: std::sync::Arc<vulkano::memory::allocator::StandardMemoryAllocator> = return;
/// # let command_buffer_allocator: vulkano::command_buffer::allocator::StandardCommandBufferAllocator = return; /// # let command_buffer_allocator: std::sync::Arc<vulkano::command_buffer::allocator::StandardCommandBufferAllocator> = return;
/// # /// #
/// // Create the buffer allocator. /// // Create the buffer allocator.
/// let buffer_allocator = SubbufferAllocator::new( /// let buffer_allocator = SubbufferAllocator::new(
@ -108,7 +108,7 @@ const MAX_ARENAS: usize = 32;
/// ///
/// // You can then use `subbuffer` as if it was an entirely separate buffer. /// // You can then use `subbuffer` as if it was an entirely separate buffer.
/// AutoCommandBufferBuilder::primary( /// AutoCommandBufferBuilder::primary(
/// &command_buffer_allocator, /// command_buffer_allocator.clone(),
/// queue.queue_family_index(), /// queue.queue_family_index(),
/// CommandBufferUsage::OneTimeSubmit, /// CommandBufferUsage::OneTimeSubmit,
/// ) /// )
@ -117,7 +117,8 @@ const MAX_ARENAS: usize = 32;
/// // it is pointless to do that. /// // it is pointless to do that.
/// .update_buffer(subbuffer.clone(), &[0.2, 0.3, 0.4, 0.5]) /// .update_buffer(subbuffer.clone(), &[0.2, 0.3, 0.4, 0.5])
/// .unwrap() /// .unwrap()
/// .build().unwrap() /// .build()
/// .unwrap()
/// .execute(queue.clone()) /// .execute(queue.clone())
/// .unwrap() /// .unwrap()
/// .then_signal_fence_and_flush() /// .then_signal_fence_and_flush()

View File

@ -133,7 +133,7 @@ pub mod view;
/// # let device: std::sync::Arc<vulkano::device::Device> = return; /// # let device: std::sync::Arc<vulkano::device::Device> = return;
/// # let queue: std::sync::Arc<vulkano::device::Queue> = return; /// # let queue: std::sync::Arc<vulkano::device::Queue> = return;
/// # let memory_allocator: std::sync::Arc<vulkano::memory::allocator::StandardMemoryAllocator> = return; /// # let memory_allocator: std::sync::Arc<vulkano::memory::allocator::StandardMemoryAllocator> = return;
/// # let command_buffer_allocator: vulkano::command_buffer::allocator::StandardCommandBufferAllocator = return; /// # let command_buffer_allocator: std::sync::Arc<vulkano::command_buffer::allocator::StandardCommandBufferAllocator> = return;
/// # /// #
/// // Simple iterator to construct test data. /// // Simple iterator to construct test data.
/// let data = (0..10_000).map(|i| i as f32); /// let data = (0..10_000).map(|i| i as f32);
@ -175,7 +175,7 @@ pub mod view;
/// ///
/// // Create a one-time command to copy between the buffers. /// // Create a one-time command to copy between the buffers.
/// let mut cbb = AutoCommandBufferBuilder::primary( /// let mut cbb = AutoCommandBufferBuilder::primary(
/// &command_buffer_allocator, /// command_buffer_allocator.clone(),
/// queue.queue_family_index(), /// queue.queue_family_index(),
/// CommandBufferUsage::OneTimeSubmit, /// CommandBufferUsage::OneTimeSubmit,
/// ) /// )

View File

@ -14,18 +14,16 @@ use super::{
use crate::{ use crate::{
device::{Device, DeviceOwned}, device::{Device, DeviceOwned},
instance::InstanceOwnedDebugWrapper, instance::InstanceOwnedDebugWrapper,
Validated, VulkanError, Validated, ValidationError, VulkanError,
}; };
use crossbeam_queue::ArrayQueue; use crossbeam_queue::ArrayQueue;
use smallvec::{IntoIter, SmallVec}; use smallvec::SmallVec;
use std::{ use std::{
cell::{Cell, UnsafeCell}, cell::UnsafeCell,
error::Error, error::Error,
fmt::Display, fmt::{Debug, Display, Error as FmtError, Formatter},
marker::PhantomData, mem, ptr,
mem::ManuallyDrop, sync::{Arc, Weak},
sync::Arc,
thread,
}; };
use thread_local::ThreadLocal; use thread_local::ThreadLocal;
@ -36,66 +34,126 @@ const MAX_POOLS: usize = 32;
/// # Safety /// # Safety
/// ///
/// A Vulkan command pool must be externally synchronized as if it owned the command buffers that /// A Vulkan command pool must be externally synchronized as if it owned the command buffers that
/// were allocated from it. This includes allocating from the pool, freeing from the pool, resetting /// were allocated from it. This includes allocating from the pool, freeing from the pool,
/// the pool or individual command buffers, and most importantly recording commands to command /// resetting the pool or individual command buffers, and most importantly recording commands to
/// buffers. The implementation of `CommandBufferAllocator` is expected to manage this. /// command buffers. The implementation of `CommandBufferAllocator` is expected to manage this.
/// ///
/// The destructors of the [`CommandBufferBuilderAlloc`] and the [`CommandBufferAlloc`] are expected /// The implementation of `allocate` must return a valid allocation that stays allocated until
/// to free the command buffer, reset the command buffer, or add it to a pool so that it gets /// either `deallocate` is called on it or the allocator is dropped. If the allocator is cloned, it
/// reused. If the implementation frees or resets the command buffer, it must not forget that this /// must produce the same allocator, and an allocation must stay allocated until either
/// operation must be externally synchronized. /// `deallocate` is called on any of the clones or all clones have been dropped.
pub unsafe trait CommandBufferAllocator: DeviceOwned { ///
/// See [`allocate`](Self::allocate). /// The implementation of `deallocate` is expected to free the command buffer, reset the command
type Iter: Iterator<Item = Self::Builder>; /// buffer or its pool, or add it to a pool so that it gets reused. If the implementation frees the
/// command buffer or resets the command buffer or pool, it must not forget that this operation
/// Represents a command buffer that has been allocated and that is currently being built. /// must be externally synchronized. The implementation should not panic as it is used when
type Builder: CommandBufferBuilderAlloc<Alloc = Self::Alloc>; /// dropping command buffers.
///
/// Represents a command buffer that has been allocated and that is pending execution or is /// Command buffers in the recording state can never be sent between threads in vulkano, which
/// being executed. /// means that the implementation of `allocate` can freely assume that the command buffer won't
type Alloc: CommandBufferAlloc; /// leave the thread it was allocated on until it has finished recording. Note however that after
/// recording is finished, command buffers are free to be sent between threads, which means that
/// Allocates command buffers. /// `deallocate` must account for the possibility that a command buffer can be deallocated from a
/// /// different thread than it was allocated from.
/// Returns an iterator that contains the requested amount of allocated command buffers. pub unsafe trait CommandBufferAllocator: DeviceOwned + Send + Sync + 'static {
/// Allocates a command buffer.
fn allocate( fn allocate(
&self, &self,
queue_family_index: u32, queue_family_index: u32,
level: CommandBufferLevel, level: CommandBufferLevel,
command_buffer_count: u32, ) -> Result<CommandBufferAlloc, Validated<VulkanError>>;
) -> Result<Self::Iter, VulkanError>;
/// Deallocates the given `allocation`.
///
/// # Safety
///
/// - `allocation` must refer to a **currently allocated** allocation of `self`.
unsafe fn deallocate(&self, allocation: CommandBufferAlloc);
} }
/// A command buffer allocated from a pool and that can be recorded. impl Debug for dyn CommandBufferAllocator {
/// fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
/// # Safety f.debug_struct("CommandBufferAllocator")
/// .finish_non_exhaustive()
/// See [`CommandBufferAllocator`] for information about safety. }
pub unsafe trait CommandBufferBuilderAlloc: DeviceOwned {
/// Return type of `into_alloc`.
type Alloc: CommandBufferAlloc;
/// Returns the internal object that contains the command buffer.
fn inner(&self) -> &CommandPoolAlloc;
/// Turns this builder into a command buffer that is pending execution.
fn into_alloc(self) -> Self::Alloc;
/// Returns the index of the queue family that the pool targets.
fn queue_family_index(&self) -> u32;
} }
/// A command buffer allocated from a pool that has finished being recorded. /// An allocation made using a [command buffer allocator].
/// ///
/// # Safety /// [command buffer allocator]: CommandBufferAllocator
/// #[derive(Debug)]
/// See [`CommandBufferAllocator`] for information about safety. pub struct CommandBufferAlloc {
pub unsafe trait CommandBufferAlloc: DeviceOwned + Send + Sync + 'static { /// The internal object that contains the command buffer.
/// Returns the internal object that contains the command buffer. pub inner: CommandPoolAlloc,
fn inner(&self) -> &CommandPoolAlloc;
/// Returns the index of the queue family that the pool targets. /// The command pool that the command buffer was allocated from.
fn queue_family_index(&self) -> u32; ///
/// Using this for anything other than looking at the pool's metadata will lead to a Bad
/// Time<sup>TM</sup>.
pub pool: Arc<CommandPool>,
/// An opaque handle identifying the allocation inside the allocator.
pub handle: AllocationHandle,
}
/// An opaque handle identifying an allocation inside an allocator.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(not(doc), repr(transparent))]
pub struct AllocationHandle(*mut ());
unsafe impl Send for AllocationHandle {}
unsafe impl Sync for AllocationHandle {}
impl AllocationHandle {
/// Creates a null `AllocationHandle`.
///
/// Use this if you don't have anything that you need to associate with the allocation.
#[inline]
pub const fn null() -> Self {
AllocationHandle(ptr::null_mut())
}
/// Stores a pointer in an `AllocationHandle`.
///
/// Use this if you want to associate an allocation with some (host) heap allocation.
#[inline]
pub const fn from_ptr(ptr: *mut ()) -> Self {
AllocationHandle(ptr)
}
/// Stores an index inside an `AllocationHandle`.
///
/// Use this if you want to associate an allocation with some index.
#[allow(clippy::useless_transmute)]
#[inline]
pub const fn from_index(index: usize) -> Self {
// SAFETY: `usize` and `*mut ()` have the same layout.
AllocationHandle(unsafe { mem::transmute::<usize, *mut ()>(index) })
}
/// Retrieves a previously-stored pointer from the `AllocationHandle`.
///
/// If this handle hasn't been created using [`from_ptr`] then this will return an invalid
/// pointer, dereferencing which is undefined behavior.
///
/// [`from_ptr`]: Self::from_ptr
#[inline]
pub const fn as_ptr(self) -> *mut () {
self.0
}
/// Retrieves a previously-stored index from the `AllocationHandle`.
///
/// If this handle hasn't been created using [`from_index`] then this will return a bogus
/// result.
///
/// [`from_index`]: Self::from_index
#[allow(clippy::transmutes_expressible_as_ptr_casts)]
#[inline]
pub const fn as_index(self) -> usize {
// SAFETY: `usize` and `*mut ()` have the same layout.
unsafe { mem::transmute::<*mut (), usize>(self.0) }
}
} }
/// Standard implementation of a command buffer allocator. /// Standard implementation of a command buffer allocator.
@ -115,25 +173,26 @@ pub unsafe trait CommandBufferAlloc: DeviceOwned + Send + Sync + 'static {
/// ///
/// This allocator only needs to lock when a thread first allocates or when a thread that /// This allocator only needs to lock when a thread first allocates or when a thread that
/// previously allocated exits. In all other cases, allocation is lock-free. /// previously allocated exits. In all other cases, allocation is lock-free.
///
/// Command buffers can't be moved between threads during the building process, but finished command
/// buffers can. When a command buffer is dropped, it is returned back to the pool for reuse.
#[derive(Debug)] #[derive(Debug)]
pub struct StandardCommandBufferAllocator { pub struct StandardCommandBufferAllocator {
device: InstanceOwnedDebugWrapper<Arc<Device>>, device: InstanceOwnedDebugWrapper<Arc<Device>>,
// Each queue family index points directly to its entry. // Each queue family index points directly to its entry.
pools: ThreadLocal<SmallVec<[UnsafeCell<Option<Entry>>; 8]>>, pools: ThreadLocal<SmallVec<[UnsafeCell<Option<Entry>>; 8]>>,
create_info: StandardCommandBufferAllocatorCreateInfo, buffer_count: [usize; 2],
} }
impl StandardCommandBufferAllocator { impl StandardCommandBufferAllocator {
/// Creates a new `StandardCommandBufferAllocator`. /// Creates a new `StandardCommandBufferAllocator`.
#[inline] #[inline]
pub fn new(device: Arc<Device>, create_info: StandardCommandBufferAllocatorCreateInfo) -> Self { pub fn new(device: Arc<Device>, create_info: StandardCommandBufferAllocatorCreateInfo) -> Self {
let mut buffer_count = [0, 0];
buffer_count[CommandBufferLevel::Primary as usize] = create_info.primary_buffer_count;
buffer_count[CommandBufferLevel::Secondary as usize] = create_info.secondary_buffer_count;
StandardCommandBufferAllocator { StandardCommandBufferAllocator {
device: InstanceOwnedDebugWrapper(device), device: InstanceOwnedDebugWrapper(device),
pools: ThreadLocal::new(), pools: ThreadLocal::new(),
create_info, buffer_count,
} }
} }
@ -193,95 +252,92 @@ impl StandardCommandBufferAllocator {
} }
unsafe impl CommandBufferAllocator for StandardCommandBufferAllocator { unsafe impl CommandBufferAllocator for StandardCommandBufferAllocator {
type Iter = IntoIter<[StandardCommandBufferBuilderAlloc; 1]>;
type Builder = StandardCommandBufferBuilderAlloc;
type Alloc = StandardCommandBufferAlloc;
/// Allocates command buffers.
///
/// Returns an iterator that contains the requested amount of allocated command buffers.
///
/// # Panics
///
/// - Panics if the queue family index is not active on the device.
/// - Panics if `command_buffer_count` exceeds the count configured for the pool corresponding
/// to `level`.
#[inline] #[inline]
fn allocate( fn allocate(
&self, &self,
queue_family_index: u32, queue_family_index: u32,
level: CommandBufferLevel, level: CommandBufferLevel,
command_buffer_count: u32, ) -> Result<CommandBufferAlloc, Validated<VulkanError>> {
) -> Result<Self::Iter, VulkanError> { if !self
// VUID-vkCreateCommandPool-queueFamilyIndex-01937
assert!(self
.device .device
.active_queue_family_indices() .active_queue_family_indices()
.contains(&queue_family_index)); .contains(&queue_family_index)
{
Err(Box::new(ValidationError {
context: "queue_family_index".into(),
problem: "is not active on the device".into(),
vuids: &["VUID-vkCreateCommandPool-queueFamilyIndex-01937"],
..Default::default()
}))?;
}
let entry = unsafe { &mut *self.entry(queue_family_index) }; let entry = unsafe { &mut *self.entry(queue_family_index) };
if entry.is_none() { if entry.is_none() {
let reserve = Arc::new(ArrayQueue::new(MAX_POOLS)); *entry = Some(Entry::new(
*entry = Some(Entry { self.device.clone(),
pool: Pool::new( queue_family_index,
self.device.clone(), &self.buffer_count,
queue_family_index, Arc::new(ArrayQueue::new(MAX_POOLS)),
reserve.clone(), )?);
&self.create_info,
)?,
reserve,
});
} }
let entry = entry.as_mut().unwrap(); let entry = entry.as_mut().unwrap();
// First try to allocate from existing command buffers. Ok(entry.allocate(queue_family_index, level, &self.buffer_count)?)
if let Some(allocs) = entry.pool.allocate(level, command_buffer_count) { }
return Ok(allocs);
}
// Else try to reset the pool. #[inline]
if entry unsafe fn deallocate(&self, allocation: CommandBufferAlloc) {
.try_reset_pool(CommandPoolResetFlags::empty()) let ptr = allocation.handle.as_ptr().cast::<Pool>();
.is_err()
{
// If that fails too try to grab a pool from the reserve.
entry.pool = if let Some(inner) = entry.reserve.pop() {
Arc::new(Pool {
inner: ManuallyDrop::new(inner),
reserve: entry.reserve.clone(),
})
} else {
// Else we are unfortunately forced to create a new pool.
Pool::new(
self.device.clone(),
queue_family_index,
entry.reserve.clone(),
&self.create_info,
)?
};
}
Ok(entry.pool.allocate(level, command_buffer_count).unwrap()) // SAFETY: The caller must guarantee that `allocation` refers to one allocated by `self`,
// therefore `ptr` must be the same one we gave out on allocation. We also know that the
// pointer must be valid, because the caller must guarantee that the same allocation isn't
// deallocated more than once. That means that since we cloned the `Arc` on allocation, at
// least that strong reference must still keep it alive, and we can safely drop this clone
// at the end of the scope here.
let pool = unsafe { Arc::from_raw(ptr) };
let level = allocation.inner.level();
// This cannot panic because in order to have allocated a command buffer with the level in
// the first place, the size of the pool for that level must have been non-zero.
let buffer_reserve = pool.buffer_reserve[level as usize].as_ref().unwrap();
// This cannot happen because every allocation is (supposed to be) returned to the pool
// whence it came, so there must be enough room for it.
debug_assert!(buffer_reserve.push(allocation.inner).is_ok());
// We have to make sure that we only reset the pool under this condition, because there
// could be other references in other allocations.
if Arc::strong_count(&pool) == 1 {
// The pool reserve can be dropped from under us when an entry is cleared, in which
// case we destroy the pool.
if let Some(reserve) = pool.pool_reserve.upgrade() {
// If there is not enough space in the reserve, we destroy the pool. The only way
// this can happen is if something is resource hogging, forcing new pools to be
// created such that the number exceeds `MAX_POOLS`, and then drops them all at
// once.
let _ = reserve.push(pool);
}
}
} }
} }
unsafe impl<T: CommandBufferAllocator> CommandBufferAllocator for Arc<T> { unsafe impl<T: CommandBufferAllocator> CommandBufferAllocator for Arc<T> {
type Iter = T::Iter;
type Builder = T::Builder;
type Alloc = T::Alloc;
#[inline] #[inline]
fn allocate( fn allocate(
&self, &self,
queue_family_index: u32, queue_family_index: u32,
level: CommandBufferLevel, level: CommandBufferLevel,
command_buffer_count: u32, ) -> Result<CommandBufferAlloc, Validated<VulkanError>> {
) -> Result<Self::Iter, VulkanError> { (**self).allocate(queue_family_index, level)
(**self).allocate(queue_family_index, level, command_buffer_count) }
#[inline]
unsafe fn deallocate(&self, allocation: CommandBufferAlloc) {
(**self).deallocate(allocation)
} }
} }
@ -296,32 +352,108 @@ unsafe impl DeviceOwned for StandardCommandBufferAllocator {
struct Entry { struct Entry {
// Contains the actual Vulkan command pool that is currently in use. // Contains the actual Vulkan command pool that is currently in use.
pool: Arc<Pool>, pool: Arc<Pool>,
// When a `Pool` is dropped, it returns itself here for reuse. // How many command buffers have been allocated from `pool.buffer_reserve`.
reserve: Arc<ArrayQueue<PoolInner>>, allocations: [usize; 2],
// When a `Pool` is about to be dropped, it is returned here for reuse.
pool_reserve: Arc<ArrayQueue<Arc<Pool>>>,
} }
// This is needed because of the blanket impl of `Send` on `Arc<T>`, which requires that `T` is // This is needed because of the blanket impl of `Send` on `Arc<T>`, which requires that `T` is
// `Send + Sync`. `Pool` is `Send + !Sync` because `CommandPool` is `!Sync`. That's fine however // `Send + Sync`. `Pool` is `Send + !Sync` because `CommandPool` is `!Sync`. That's fine however
// because we never access the Vulkan command pool concurrently. Same goes for the `Cell`s. // because we never access the Vulkan command pool concurrently.
unsafe impl Send for Entry {} unsafe impl Send for Entry {}
impl Entry { impl Entry {
fn new(
device: Arc<Device>,
queue_family_index: u32,
buffer_count: &[usize; 2],
pool_reserve: Arc<ArrayQueue<Arc<Pool>>>,
) -> Result<Self, VulkanError> {
Ok(Entry {
pool: Pool::new(device, queue_family_index, buffer_count, &pool_reserve)?,
allocations: [0; 2],
pool_reserve,
})
}
fn allocate(
&mut self,
queue_family_index: u32,
level: CommandBufferLevel,
buffer_count: &[usize; 2],
) -> Result<CommandBufferAlloc, VulkanError> {
if self.allocations[level as usize] >= buffer_count[level as usize] {
// This can happen if there's only ever one allocation alive at any point in time. In
// that case, when deallocating the last command buffer before reaching `buffer_count`,
// there will be 2 references to the pool (one here and one in the allocation) and so
// the pool won't be returned to the reserve when deallocating. However, since there
// are no other allocations alive, there would be no other allocations that could
// return it to the reserve. To avoid dropping the pool unneccessarily, we simply
// continue using it. In the case where there are other references, we drop ours, at
// which point an allocation still holding a reference will be able to put the pool
// into the reserve when deallocated.
//
// TODO: This can still run into the A/B/A problem causing the pool to be dropped.
if Arc::strong_count(&self.pool) == 1 {
// SAFETY: We checked that the pool has a single strong reference above, meaning
// that all the allocations we gave out must have been deallocated.
unsafe {
self.pool
.inner
.reset_unchecked(CommandPoolResetFlags::empty())
}?;
self.allocations = [0; 2];
} else {
if let Some(pool) = self.pool_reserve.pop() {
// SAFETY: We checked that the pool has a single strong reference when
// deallocating, meaning that all the allocations we gave out must have been
// deallocated.
unsafe { pool.inner.reset_unchecked(CommandPoolResetFlags::empty()) }?;
self.pool = pool;
self.allocations = [0; 2];
} else {
*self = Entry::new(
self.pool.inner.device().clone(),
queue_family_index,
buffer_count,
self.pool_reserve.clone(),
)?;
}
}
}
let buffer_reserve = self.pool.buffer_reserve[level as usize]
.as_ref()
.unwrap_or_else(|| {
panic!(
"attempted to allocate a command buffer with level `{level:?}`, but the \
command buffer pool for that level was configured to be empty",
)
});
self.allocations[level as usize] += 1;
Ok(CommandBufferAlloc {
inner: buffer_reserve.pop().unwrap(),
pool: self.pool.inner.clone(),
handle: AllocationHandle::from_ptr(Arc::into_raw(self.pool.clone()) as _),
})
}
fn try_reset_pool( fn try_reset_pool(
&mut self, &mut self,
flags: CommandPoolResetFlags, flags: CommandPoolResetFlags,
) -> Result<(), Validated<ResetCommandPoolError>> { ) -> Result<(), Validated<ResetCommandPoolError>> {
if let Some(pool) = Arc::get_mut(&mut self.pool) { if let Some(pool) = Arc::get_mut(&mut self.pool) {
unsafe { unsafe { pool.inner.reset(flags) }.map_err(|err| match err {
pool.inner.inner.reset(flags).map_err(|err| match err { Validated::Error(err) => Validated::Error(ResetCommandPoolError::VulkanError(err)),
Validated::Error(err) => { Validated::ValidationError(err) => err.into(),
Validated::Error(ResetCommandPoolError::VulkanError(err)) })?;
}
Validated::ValidationError(err) => err.into(),
})?
};
*pool.inner.primary_allocations.get_mut() = 0; self.allocations = [0; 2];
*pool.inner.secondary_allocations.get_mut() = 0;
Ok(()) Ok(())
} else { } else {
@ -332,31 +464,20 @@ impl Entry {
#[derive(Debug)] #[derive(Debug)]
struct Pool { struct Pool {
inner: ManuallyDrop<PoolInner>,
// Where we return the `PoolInner` in our `Drop` impl.
reserve: Arc<ArrayQueue<PoolInner>>,
}
#[derive(Debug)]
struct PoolInner {
// The Vulkan pool specific to a device's queue family. // The Vulkan pool specific to a device's queue family.
inner: CommandPool, inner: Arc<CommandPool>,
// List of existing primary command buffers that are available for reuse. // List of existing command buffers that are available for reuse.
primary_pool: Option<ArrayQueue<CommandPoolAlloc>>, buffer_reserve: [Option<ArrayQueue<CommandPoolAlloc>>; 2],
// List of existing secondary command buffers that are available for reuse. // Where to return this pool once there are no more current allocations.
secondary_pool: Option<ArrayQueue<CommandPoolAlloc>>, pool_reserve: Weak<ArrayQueue<Arc<Self>>>,
// How many command buffers have been allocated from `self.primary_pool`.
primary_allocations: Cell<usize>,
// How many command buffers have been allocated from `self.secondary_pool`.
secondary_allocations: Cell<usize>,
} }
impl Pool { impl Pool {
fn new( fn new(
device: Arc<Device>, device: Arc<Device>,
queue_family_index: u32, queue_family_index: u32,
reserve: Arc<ArrayQueue<PoolInner>>, buffer_counts: &[usize; 2],
create_info: &StandardCommandBufferAllocatorCreateInfo, pool_reserve: &Arc<ArrayQueue<Arc<Self>>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let inner = CommandPool::new( let inner = CommandPool::new(
device, device,
@ -367,152 +488,33 @@ impl Pool {
) )
.map_err(Validated::unwrap)?; .map_err(Validated::unwrap)?;
let primary_pool = if create_info.primary_buffer_count > 0 { let levels = [CommandBufferLevel::Primary, CommandBufferLevel::Secondary];
let pool = ArrayQueue::new(create_info.primary_buffer_count); let mut buffer_reserve = [None, None];
for alloc in inner.allocate_command_buffers(CommandBufferAllocateInfo { for (level, &buffer_count) in levels.into_iter().zip(buffer_counts) {
level: CommandBufferLevel::Primary, if buffer_count == 0 {
command_buffer_count: create_info.primary_buffer_count as u32, continue;
..Default::default()
})? {
let _ = pool.push(alloc);
} }
Some(pool) let pool = ArrayQueue::new(buffer_count);
} else {
None
};
let secondary_pool = if create_info.secondary_buffer_count > 0 { for allocation in inner.allocate_command_buffers(CommandBufferAllocateInfo {
let pool = ArrayQueue::new(create_info.secondary_buffer_count); level,
command_buffer_count: buffer_count.try_into().unwrap(),
for alloc in inner.allocate_command_buffers(CommandBufferAllocateInfo {
level: CommandBufferLevel::Secondary,
command_buffer_count: create_info.secondary_buffer_count as u32,
..Default::default() ..Default::default()
})? { })? {
let _ = pool.push(alloc); let _ = pool.push(allocation);
} }
Some(pool) buffer_reserve[level as usize] = Some(pool);
} else { }
None
};
Ok(Arc::new(Pool { Ok(Arc::new(Pool {
inner: ManuallyDrop::new(PoolInner { inner: Arc::new(inner),
inner, buffer_reserve,
primary_pool, pool_reserve: Arc::downgrade(pool_reserve),
secondary_pool,
primary_allocations: Cell::new(0),
secondary_allocations: Cell::new(0),
}),
reserve,
})) }))
} }
fn allocate(
self: &Arc<Self>,
level: CommandBufferLevel,
command_buffer_count: u32,
) -> Option<IntoIter<[StandardCommandBufferBuilderAlloc; 1]>> {
let command_buffer_count = command_buffer_count as usize;
match level {
CommandBufferLevel::Primary => {
if let Some(pool) = &self.inner.primary_pool {
let count = self.inner.primary_allocations.get();
if count + command_buffer_count <= pool.capacity() {
let mut output = SmallVec::<[_; 1]>::with_capacity(command_buffer_count);
for _ in 0..command_buffer_count {
output.push(StandardCommandBufferBuilderAlloc {
inner: StandardCommandBufferAlloc {
inner: ManuallyDrop::new(pool.pop().unwrap()),
pool: self.clone(),
},
_marker: PhantomData,
});
}
self.inner
.primary_allocations
.set(count + command_buffer_count);
Some(output.into_iter())
} else if command_buffer_count > pool.capacity() {
panic!(
"command buffer count ({}) exceeds the capacity of the primary command \
buffer pool ({})",
command_buffer_count, pool.capacity(),
);
} else {
None
}
} else {
panic!(
"attempted to allocate a primary command buffer when the primary command \
buffer pool was configured to be empty",
);
}
}
CommandBufferLevel::Secondary => {
if let Some(pool) = &self.inner.secondary_pool {
let count = self.inner.secondary_allocations.get();
if count + command_buffer_count <= pool.capacity() {
let mut output = SmallVec::<[_; 1]>::with_capacity(command_buffer_count);
for _ in 0..command_buffer_count {
output.push(StandardCommandBufferBuilderAlloc {
inner: StandardCommandBufferAlloc {
inner: ManuallyDrop::new(pool.pop().unwrap()),
pool: self.clone(),
},
_marker: PhantomData,
});
}
self.inner
.secondary_allocations
.set(count + command_buffer_count);
Some(output.into_iter())
} else if command_buffer_count > pool.capacity() {
panic!(
"command buffer count ({}) exceeds the capacity of the secondary \
command buffer pool ({})",
command_buffer_count,
pool.capacity(),
);
} else {
None
}
} else {
panic!(
"attempted to allocate a secondary command buffer when the secondary \
command buffer pool was configured to be empty",
);
}
}
}
}
}
impl Drop for Pool {
fn drop(&mut self) {
let inner = unsafe { ManuallyDrop::take(&mut self.inner) };
if thread::panicking() {
return;
}
unsafe { inner.inner.reset(CommandPoolResetFlags::empty()) }.unwrap();
inner.primary_allocations.set(0);
inner.secondary_allocations.set(0);
// If there is not enough space in the reserve, we destroy the pool. The only way this can
// happen is if something is resource hogging, forcing new pools to be created such that
// the number exceeds `MAX_POOLS`, and then drops them all at once.
let _ = self.reserve.push(inner);
}
} }
/// Parameters to create a new [`StandardCommandBufferAllocator`]. /// Parameters to create a new [`StandardCommandBufferAllocator`].
@ -552,89 +554,6 @@ impl Default for StandardCommandBufferAllocatorCreateInfo {
} }
} }
/// Command buffer allocated from a [`StandardCommandBufferAllocator`] that is currently being
/// built.
pub struct StandardCommandBufferBuilderAlloc {
// The only difference between a `StandardCommandBufferBuilder` and a
// `StandardCommandBufferAlloc` is that the former must not implement `Send` and `Sync`.
// Therefore we just share the structs.
inner: StandardCommandBufferAlloc,
// Unimplemented `Send` and `Sync` from the builder.
_marker: PhantomData<*const ()>,
}
unsafe impl CommandBufferBuilderAlloc for StandardCommandBufferBuilderAlloc {
type Alloc = StandardCommandBufferAlloc;
#[inline]
fn inner(&self) -> &CommandPoolAlloc {
self.inner.inner()
}
#[inline]
fn into_alloc(self) -> Self::Alloc {
self.inner
}
#[inline]
fn queue_family_index(&self) -> u32 {
self.inner.queue_family_index()
}
}
unsafe impl DeviceOwned for StandardCommandBufferBuilderAlloc {
#[inline]
fn device(&self) -> &Arc<Device> {
self.inner.device()
}
}
/// Command buffer allocated from a [`StandardCommandBufferAllocator`].
pub struct StandardCommandBufferAlloc {
// The actual command buffer. Extracted in the `Drop` implementation.
inner: ManuallyDrop<CommandPoolAlloc>,
// We hold a reference to the pool for our destructor.
pool: Arc<Pool>,
}
// It's fine to share `Pool` between threads because we never access the Vulkan command pool
// concurrently. Same goes for the `Cell`s.
unsafe impl Send for StandardCommandBufferAlloc {}
unsafe impl Sync for StandardCommandBufferAlloc {}
unsafe impl CommandBufferAlloc for StandardCommandBufferAlloc {
#[inline]
fn inner(&self) -> &CommandPoolAlloc {
&self.inner
}
#[inline]
fn queue_family_index(&self) -> u32 {
self.pool.inner.inner.queue_family_index()
}
}
unsafe impl DeviceOwned for StandardCommandBufferAlloc {
#[inline]
fn device(&self) -> &Arc<Device> {
self.pool.inner.inner.device()
}
}
impl Drop for StandardCommandBufferAlloc {
#[inline]
fn drop(&mut self) {
let inner = unsafe { ManuallyDrop::take(&mut self.inner) };
let pool = match inner.level() {
CommandBufferLevel::Primary => &self.pool.inner.primary_pool,
CommandBufferLevel::Secondary => &self.pool.inner.secondary_pool,
};
// This can't panic, because if an allocation from a particular kind of pool was made, then
// the pool must exist.
let _ = pool.as_ref().unwrap().push(inner);
}
}
/// Error that can be returned when resetting a [`CommandPool`]. /// Error that can be returned when resetting a [`CommandPool`].
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum ResetCommandPoolError { pub enum ResetCommandPoolError {
@ -648,7 +567,7 @@ pub enum ResetCommandPoolError {
impl Error for ResetCommandPoolError {} impl Error for ResetCommandPoolError {}
impl Display for ResetCommandPoolError { impl Display for ResetCommandPoolError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::VulkanError(_) => write!(f, "a runtime error occurred"), Self::VulkanError(_) => write!(f, "a runtime error occurred"),
Self::InUse => write!(f, "the command pool is still in use"), Self::InUse => write!(f, "the command pool is still in use"),
@ -667,44 +586,3 @@ impl From<ResetCommandPoolError> for Validated<ResetCommandPoolError> {
Self::Error(err) Self::Error(err)
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::VulkanObject;
use std::thread;
#[test]
fn threads_use_different_pools() {
let (device, queue) = gfx_dev_and_queue!();
let allocator = StandardCommandBufferAllocator::new(device, Default::default());
let pool1 = allocator
.allocate(queue.queue_family_index(), CommandBufferLevel::Primary, 1)
.unwrap()
.next()
.unwrap()
.into_alloc()
.pool
.inner
.inner
.handle();
thread::spawn(move || {
let pool2 = allocator
.allocate(queue.queue_family_index(), CommandBufferLevel::Primary, 1)
.unwrap()
.next()
.unwrap()
.into_alloc()
.pool
.inner
.inner
.handle();
assert_ne!(pool1, pool2);
})
.join()
.unwrap();
}
}

View File

@ -5,7 +5,7 @@ use super::{
use crate::{ use crate::{
buffer::{Buffer, IndexBuffer, Subbuffer}, buffer::{Buffer, IndexBuffer, Subbuffer},
command_buffer::{ command_buffer::{
allocator::{CommandBufferAllocator, StandardCommandBufferAllocator}, allocator::CommandBufferAllocator,
sys::{CommandBufferBeginInfo, UnsafeCommandBuffer, UnsafeCommandBufferBuilder}, sys::{CommandBufferBeginInfo, UnsafeCommandBuffer, UnsafeCommandBufferBuilder},
CommandBufferBufferRangeUsage, CommandBufferBufferUsage, CommandBufferImageRangeUsage, CommandBufferBufferRangeUsage, CommandBufferBufferUsage, CommandBufferImageRangeUsage,
CommandBufferImageUsage, CommandBufferInheritanceInfo, CommandBufferImageUsage, CommandBufferInheritanceInfo,
@ -54,31 +54,24 @@ use std::{
/// the `Send` and `Sync` traits. If you use this allocator, then the `AutoCommandBufferBuilder` /// the `Send` and `Sync` traits. If you use this allocator, then the `AutoCommandBufferBuilder`
/// will not implement `Send` and `Sync` either. Once a command buffer is built, however, it *does* /// will not implement `Send` and `Sync` either. Once a command buffer is built, however, it *does*
/// implement `Send` and `Sync`. /// implement `Send` and `Sync`.
pub struct AutoCommandBufferBuilder<L, A = StandardCommandBufferAllocator> pub struct AutoCommandBufferBuilder<L> {
where pub(in crate::command_buffer) inner: UnsafeCommandBufferBuilder,
A: CommandBufferAllocator,
{
pub(in crate::command_buffer) inner: UnsafeCommandBufferBuilder<A>,
commands: Vec<( commands: Vec<(
CommandInfo, CommandInfo,
Box<dyn Fn(&mut UnsafeCommandBufferBuilder<A>) + Send + Sync + 'static>, Box<dyn Fn(&mut UnsafeCommandBufferBuilder) + Send + Sync + 'static>,
)>, )>,
pub(in crate::command_buffer) builder_state: CommandBufferBuilderState, pub(in crate::command_buffer) builder_state: CommandBufferBuilderState,
_data: PhantomData<L>, _data: PhantomData<L>,
} }
impl<A> AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, A> impl AutoCommandBufferBuilder<PrimaryAutoCommandBuffer> {
where
A: CommandBufferAllocator,
{
/// Starts recording a primary command buffer. /// Starts recording a primary command buffer.
#[inline] #[inline]
pub fn primary( pub fn primary(
allocator: &A, allocator: Arc<dyn CommandBufferAllocator>,
queue_family_index: u32, queue_family_index: u32,
usage: CommandBufferUsage, usage: CommandBufferUsage,
) -> Result<AutoCommandBufferBuilder<PrimaryAutoCommandBuffer<A>, A>, Validated<VulkanError>> ) -> Result<AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, Validated<VulkanError>> {
{
unsafe { unsafe {
AutoCommandBufferBuilder::begin( AutoCommandBufferBuilder::begin(
allocator, allocator,
@ -96,10 +89,10 @@ where
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline] #[inline]
pub unsafe fn primary_unchecked( pub unsafe fn primary_unchecked(
allocator: &A, allocator: Arc<dyn CommandBufferAllocator>,
queue_family_index: u32, queue_family_index: u32,
usage: CommandBufferUsage, usage: CommandBufferUsage,
) -> Result<AutoCommandBufferBuilder<PrimaryAutoCommandBuffer<A>, A>, VulkanError> { ) -> Result<AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, Validated<VulkanError>> {
AutoCommandBufferBuilder::begin_unchecked( AutoCommandBufferBuilder::begin_unchecked(
allocator, allocator,
queue_family_index, queue_family_index,
@ -113,19 +106,15 @@ where
} }
} }
impl<A> AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, A> impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer> {
where
A: CommandBufferAllocator,
{
/// Starts recording a secondary command buffer. /// Starts recording a secondary command buffer.
#[inline] #[inline]
pub fn secondary( pub fn secondary(
allocator: &A, allocator: Arc<dyn CommandBufferAllocator>,
queue_family_index: u32, queue_family_index: u32,
usage: CommandBufferUsage, usage: CommandBufferUsage,
inheritance_info: CommandBufferInheritanceInfo, inheritance_info: CommandBufferInheritanceInfo,
) -> Result<AutoCommandBufferBuilder<SecondaryAutoCommandBuffer<A>, A>, Validated<VulkanError>> ) -> Result<AutoCommandBufferBuilder<SecondaryAutoCommandBuffer>, Validated<VulkanError>> {
{
unsafe { unsafe {
AutoCommandBufferBuilder::begin( AutoCommandBufferBuilder::begin(
allocator, allocator,
@ -143,11 +132,11 @@ where
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline] #[inline]
pub unsafe fn secondary_unchecked( pub unsafe fn secondary_unchecked(
allocator: &A, allocator: Arc<dyn CommandBufferAllocator>,
queue_family_index: u32, queue_family_index: u32,
usage: CommandBufferUsage, usage: CommandBufferUsage,
inheritance_info: CommandBufferInheritanceInfo, inheritance_info: CommandBufferInheritanceInfo,
) -> Result<AutoCommandBufferBuilder<SecondaryAutoCommandBuffer<A>, A>, VulkanError> { ) -> Result<AutoCommandBufferBuilder<SecondaryAutoCommandBuffer>, Validated<VulkanError>> {
AutoCommandBufferBuilder::begin_unchecked( AutoCommandBufferBuilder::begin_unchecked(
allocator, allocator,
queue_family_index, queue_family_index,
@ -161,31 +150,21 @@ where
} }
} }
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Actual constructor. Private. /// Actual constructor. Private.
/// ///
/// # Safety /// # Safety
/// ///
/// `begin_info.inheritance_info` must match `level`. /// `begin_info.inheritance_info` must match `level`.
unsafe fn begin( unsafe fn begin(
allocator: &A, allocator: Arc<dyn CommandBufferAllocator>,
queue_family_index: u32, queue_family_index: u32,
level: CommandBufferLevel, level: CommandBufferLevel,
begin_info: CommandBufferBeginInfo, begin_info: CommandBufferBeginInfo,
) -> Result<AutoCommandBufferBuilder<L, A>, Validated<VulkanError>> { ) -> Result<AutoCommandBufferBuilder<L>, Validated<VulkanError>> {
Self::validate_begin(allocator.device(), queue_family_index, level, &begin_info)?; Self::validate_begin(allocator.device(), queue_family_index, level, &begin_info)?;
unsafe { unsafe { Self::begin_unchecked(allocator, queue_family_index, level, begin_info) }
Ok(Self::begin_unchecked(
allocator,
queue_family_index,
level,
begin_info,
)?)
}
} }
fn validate_begin( fn validate_begin(
@ -203,11 +182,11 @@ where
#[inline] #[inline]
unsafe fn begin_unchecked( unsafe fn begin_unchecked(
allocator: &A, allocator: Arc<dyn CommandBufferAllocator>,
queue_family_index: u32, queue_family_index: u32,
level: CommandBufferLevel, level: CommandBufferLevel,
begin_info: CommandBufferBeginInfo, begin_info: CommandBufferBeginInfo,
) -> Result<Self, VulkanError> { ) -> Result<Self, Validated<VulkanError>> {
let &CommandBufferBeginInfo { let &CommandBufferBeginInfo {
usage: _, usage: _,
ref inheritance_info, ref inheritance_info,
@ -244,8 +223,8 @@ where
mut self, mut self,
) -> Result< ) -> Result<
( (
UnsafeCommandBuffer<A>, UnsafeCommandBuffer,
Vec<Box<dyn Fn(&mut UnsafeCommandBufferBuilder<A>) + Send + Sync + 'static>>, Vec<Box<dyn Fn(&mut UnsafeCommandBufferBuilder) + Send + Sync + 'static>>,
CommandBufferResourcesUsage, CommandBufferResourcesUsage,
SecondaryCommandBufferResourcesUsage, SecondaryCommandBufferResourcesUsage,
), ),
@ -327,12 +306,9 @@ where
} }
} }
impl<A> AutoCommandBufferBuilder<PrimaryAutoCommandBuffer<A>, A> impl AutoCommandBufferBuilder<PrimaryAutoCommandBuffer> {
where
A: CommandBufferAllocator,
{
/// Builds the command buffer. /// Builds the command buffer.
pub fn build(self) -> Result<Arc<PrimaryAutoCommandBuffer<A>>, Validated<VulkanError>> { pub fn build(self) -> Result<Arc<PrimaryAutoCommandBuffer>, Validated<VulkanError>> {
if self.builder_state.render_pass.is_some() { if self.builder_state.render_pass.is_some() {
return Err(Box::new(ValidationError { return Err(Box::new(ValidationError {
problem: "a render pass instance is still active".into(), problem: "a render pass instance is still active".into(),
@ -365,12 +341,9 @@ where
} }
} }
impl<A> AutoCommandBufferBuilder<SecondaryAutoCommandBuffer<A>, A> impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer> {
where
A: CommandBufferAllocator,
{
/// Builds the command buffer. /// Builds the command buffer.
pub fn build(self) -> Result<Arc<SecondaryAutoCommandBuffer<A>>, Validated<VulkanError>> { pub fn build(self) -> Result<Arc<SecondaryAutoCommandBuffer>, Validated<VulkanError>> {
if !self.builder_state.queries.is_empty() { if !self.builder_state.queries.is_empty() {
return Err(Box::new(ValidationError { return Err(Box::new(ValidationError {
problem: "a query is still active".into(), problem: "a query is still active".into(),
@ -401,15 +374,12 @@ where
} }
} }
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
pub(in crate::command_buffer) fn add_command( pub(in crate::command_buffer) fn add_command(
&mut self, &mut self,
name: &'static str, name: &'static str,
used_resources: Vec<(ResourceUseRef2, Resource)>, used_resources: Vec<(ResourceUseRef2, Resource)>,
record_func: impl Fn(&mut UnsafeCommandBufferBuilder<A>) + Send + Sync + 'static, record_func: impl Fn(&mut UnsafeCommandBufferBuilder) + Send + Sync + 'static,
) { ) {
self.commands.push(( self.commands.push((
CommandInfo { CommandInfo {
@ -425,7 +395,7 @@ where
&mut self, &mut self,
name: &'static str, name: &'static str,
used_resources: Vec<(ResourceUseRef2, Resource)>, used_resources: Vec<(ResourceUseRef2, Resource)>,
record_func: impl Fn(&mut UnsafeCommandBufferBuilder<A>) + Send + Sync + 'static, record_func: impl Fn(&mut UnsafeCommandBufferBuilder) + Send + Sync + 'static,
) { ) {
self.commands.push(( self.commands.push((
CommandInfo { CommandInfo {
@ -441,7 +411,7 @@ where
&mut self, &mut self,
name: &'static str, name: &'static str,
used_resources: Vec<(ResourceUseRef2, Resource)>, used_resources: Vec<(ResourceUseRef2, Resource)>,
record_func: impl Fn(&mut UnsafeCommandBufferBuilder<A>) + Send + Sync + 'static, record_func: impl Fn(&mut UnsafeCommandBufferBuilder) + Send + Sync + 'static,
) { ) {
self.commands.push(( self.commands.push((
CommandInfo { CommandInfo {
@ -454,10 +424,7 @@ where
} }
} }
unsafe impl<L, A> DeviceOwned for AutoCommandBufferBuilder<L, A> unsafe impl<L> DeviceOwned for AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
self.inner.device() self.inner.device()
} }

View File

@ -62,7 +62,6 @@ pub(in crate::command_buffer) use self::builder::{
RenderPassStateAttachments, RenderPassStateType, SetOrPush, RenderPassStateAttachments, RenderPassStateType, SetOrPush,
}; };
use super::{ use super::{
allocator::{CommandBufferAllocator, StandardCommandBufferAllocator},
sys::{UnsafeCommandBuffer, UnsafeCommandBufferBuilder}, sys::{UnsafeCommandBuffer, UnsafeCommandBufferBuilder},
CommandBufferInheritanceInfo, CommandBufferResourcesUsage, CommandBufferState, CommandBufferInheritanceInfo, CommandBufferResourcesUsage, CommandBufferState,
CommandBufferUsage, PrimaryCommandBufferAbstract, ResourceInCommand, CommandBufferUsage, PrimaryCommandBufferAbstract, ResourceInCommand,
@ -87,101 +86,86 @@ use std::{
mod builder; mod builder;
pub struct PrimaryAutoCommandBuffer<A = StandardCommandBufferAllocator> pub struct PrimaryAutoCommandBuffer {
where inner: UnsafeCommandBuffer,
A: CommandBufferAllocator, _keep_alive_objects: Vec<Box<dyn Fn(&mut UnsafeCommandBufferBuilder) + Send + Sync + 'static>>,
{
inner: UnsafeCommandBuffer<A>,
_keep_alive_objects:
Vec<Box<dyn Fn(&mut UnsafeCommandBufferBuilder<A>) + Send + Sync + 'static>>,
resources_usage: CommandBufferResourcesUsage, resources_usage: CommandBufferResourcesUsage,
state: Mutex<CommandBufferState>, state: Mutex<CommandBufferState>,
} }
unsafe impl<A> VulkanObject for PrimaryAutoCommandBuffer<A> unsafe impl VulkanObject for PrimaryAutoCommandBuffer {
where
A: CommandBufferAllocator,
{
type Handle = ash::vk::CommandBuffer; type Handle = ash::vk::CommandBuffer;
#[inline]
fn handle(&self) -> Self::Handle { fn handle(&self) -> Self::Handle {
self.inner.handle() self.inner.handle()
} }
} }
unsafe impl<A> DeviceOwned for PrimaryAutoCommandBuffer<A> unsafe impl DeviceOwned for PrimaryAutoCommandBuffer {
where #[inline]
A: CommandBufferAllocator,
{
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
self.inner.device() self.inner.device()
} }
} }
unsafe impl<A> PrimaryCommandBufferAbstract for PrimaryAutoCommandBuffer<A> unsafe impl PrimaryCommandBufferAbstract for PrimaryAutoCommandBuffer {
where #[inline]
A: CommandBufferAllocator,
{
fn queue_family_index(&self) -> u32 { fn queue_family_index(&self) -> u32 {
self.inner.queue_family_index() self.inner.queue_family_index()
} }
#[inline]
fn usage(&self) -> CommandBufferUsage { fn usage(&self) -> CommandBufferUsage {
self.inner.usage() self.inner.usage()
} }
#[inline]
fn state(&self) -> MutexGuard<'_, CommandBufferState> { fn state(&self) -> MutexGuard<'_, CommandBufferState> {
self.state.lock() self.state.lock()
} }
#[inline]
fn resources_usage(&self) -> &CommandBufferResourcesUsage { fn resources_usage(&self) -> &CommandBufferResourcesUsage {
&self.resources_usage &self.resources_usage
} }
} }
pub struct SecondaryAutoCommandBuffer<A = StandardCommandBufferAllocator> pub struct SecondaryAutoCommandBuffer {
where inner: UnsafeCommandBuffer,
A: CommandBufferAllocator, _keep_alive_objects: Vec<Box<dyn Fn(&mut UnsafeCommandBufferBuilder) + Send + Sync + 'static>>,
{
inner: UnsafeCommandBuffer<A>,
_keep_alive_objects:
Vec<Box<dyn Fn(&mut UnsafeCommandBufferBuilder<A>) + Send + Sync + 'static>>,
resources_usage: SecondaryCommandBufferResourcesUsage, resources_usage: SecondaryCommandBufferResourcesUsage,
submit_state: SubmitState, submit_state: SubmitState,
} }
unsafe impl<A> VulkanObject for SecondaryAutoCommandBuffer<A> unsafe impl VulkanObject for SecondaryAutoCommandBuffer {
where
A: CommandBufferAllocator,
{
type Handle = ash::vk::CommandBuffer; type Handle = ash::vk::CommandBuffer;
#[inline]
fn handle(&self) -> Self::Handle { fn handle(&self) -> Self::Handle {
self.inner.handle() self.inner.handle()
} }
} }
unsafe impl<A> DeviceOwned for SecondaryAutoCommandBuffer<A> unsafe impl DeviceOwned for SecondaryAutoCommandBuffer {
where #[inline]
A: CommandBufferAllocator,
{
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
self.inner.device() self.inner.device()
} }
} }
unsafe impl<A> SecondaryCommandBufferAbstract for SecondaryAutoCommandBuffer<A> unsafe impl SecondaryCommandBufferAbstract for SecondaryAutoCommandBuffer {
where #[inline]
A: CommandBufferAllocator,
{
fn usage(&self) -> CommandBufferUsage { fn usage(&self) -> CommandBufferUsage {
self.inner.usage() self.inner.usage()
} }
#[inline]
fn inheritance_info(&self) -> &CommandBufferInheritanceInfo { fn inheritance_info(&self) -> &CommandBufferInheritanceInfo {
self.inner.inheritance_info().as_ref().unwrap() self.inner.inheritance_info().as_ref().unwrap()
} }
#[inline]
fn lock_record(&self) -> Result<(), Box<ValidationError>> { fn lock_record(&self) -> Result<(), Box<ValidationError>> {
match self.submit_state { match self.submit_state {
SubmitState::OneTime { SubmitState::OneTime {
@ -218,6 +202,7 @@ where
Ok(()) Ok(())
} }
#[inline]
unsafe fn unlock(&self) { unsafe fn unlock(&self) {
match self.submit_state { match self.submit_state {
SubmitState::OneTime { SubmitState::OneTime {
@ -233,6 +218,7 @@ where
}; };
} }
#[inline]
fn resources_usage(&self) -> &SecondaryCommandBufferResourcesUsage { fn resources_usage(&self) -> &SecondaryCommandBufferResourcesUsage {
&self.resources_usage &self.resources_usage
} }
@ -341,10 +327,13 @@ mod tests {
fn basic_creation() { fn basic_creation() {
let (device, queue) = gfx_dev_and_queue!(); let (device, queue) = gfx_dev_and_queue!();
let allocator = StandardCommandBufferAllocator::new(device, Default::default()); let allocator = Arc::new(StandardCommandBufferAllocator::new(
device,
Default::default(),
));
AutoCommandBufferBuilder::primary( AutoCommandBufferBuilder::primary(
&allocator, allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
) )
@ -405,9 +394,12 @@ mod tests {
) )
.unwrap(); .unwrap();
let cb_allocator = StandardCommandBufferAllocator::new(device, Default::default()); let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
device,
Default::default(),
));
let mut cbb = AutoCommandBufferBuilder::primary( let mut cbb = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -443,17 +435,17 @@ mod tests {
fn secondary_nonconcurrent_conflict() { fn secondary_nonconcurrent_conflict() {
let (device, queue) = gfx_dev_and_queue!(); let (device, queue) = gfx_dev_and_queue!();
let cb_allocator = StandardCommandBufferAllocator::new( let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
device, device,
StandardCommandBufferAllocatorCreateInfo { StandardCommandBufferAllocatorCreateInfo {
secondary_buffer_count: 1, secondary_buffer_count: 1,
..Default::default() ..Default::default()
}, },
); ));
// Make a secondary CB that doesn't support simultaneous use. // Make a secondary CB that doesn't support simultaneous use.
let builder = AutoCommandBufferBuilder::secondary( let builder = AutoCommandBufferBuilder::secondary(
&cb_allocator, cb_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
Default::default(), Default::default(),
@ -463,7 +455,7 @@ mod tests {
{ {
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::SimultaneousUse, CommandBufferUsage::SimultaneousUse,
) )
@ -479,7 +471,7 @@ mod tests {
{ {
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::SimultaneousUse, CommandBufferUsage::SimultaneousUse,
) )
@ -488,7 +480,7 @@ mod tests {
let cb1 = builder.build().unwrap(); let cb1 = builder.build().unwrap();
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::SimultaneousUse, CommandBufferUsage::SimultaneousUse,
) )
@ -525,9 +517,12 @@ mod tests {
) )
.unwrap(); .unwrap();
let cb_allocator = StandardCommandBufferAllocator::new(device, Default::default()); let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
device,
Default::default(),
));
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -580,9 +575,12 @@ mod tests {
) )
.unwrap(); .unwrap();
let cb_allocator = StandardCommandBufferAllocator::new(device, Default::default()); let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
device,
Default::default(),
));
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -607,15 +605,15 @@ mod tests {
unsafe { unsafe {
let (device, queue) = gfx_dev_and_queue!(); let (device, queue) = gfx_dev_and_queue!();
let cb_allocator = StandardCommandBufferAllocator::new( let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
device.clone(), device.clone(),
StandardCommandBufferAllocatorCreateInfo { StandardCommandBufferAllocatorCreateInfo {
secondary_buffer_count: 1, secondary_buffer_count: 1,
..Default::default() ..Default::default()
}, },
); ));
let cbb = AutoCommandBufferBuilder::primary( let cbb = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -651,7 +649,7 @@ mod tests {
let secondary = (0..2) let secondary = (0..2)
.map(|_| { .map(|_| {
let mut builder = AutoCommandBufferBuilder::secondary( let mut builder = AutoCommandBufferBuilder::secondary(
&cb_allocator, cb_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::SimultaneousUse, CommandBufferUsage::SimultaneousUse,
Default::default(), Default::default(),
@ -666,7 +664,7 @@ mod tests {
{ {
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator.clone(),
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::SimultaneousUse, CommandBufferUsage::SimultaneousUse,
) )
@ -689,7 +687,7 @@ mod tests {
{ {
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::SimultaneousUse, CommandBufferUsage::SimultaneousUse,
) )
@ -711,10 +709,12 @@ mod tests {
unsafe { unsafe {
let (device, queue) = gfx_dev_and_queue!(); let (device, queue) = gfx_dev_and_queue!();
let cb_allocator = let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut sync = AutoCommandBufferBuilder::primary( let mut sync = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
) )
@ -748,10 +748,12 @@ mod tests {
unsafe { unsafe {
let (device, queue) = gfx_dev_and_queue!(); let (device, queue) = gfx_dev_and_queue!();
let cb_allocator = let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
StandardCommandBufferAllocator::new(device.clone(), Default::default()); device.clone(),
Default::default(),
));
let mut sync = AutoCommandBufferBuilder::primary( let mut sync = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::MultipleSubmit, CommandBufferUsage::MultipleSubmit,
) )

View File

@ -11,7 +11,6 @@ use crate::{
}, },
buffer::{BufferUsage, Subbuffer}, buffer::{BufferUsage, Subbuffer},
command_buffer::{ command_buffer::{
allocator::CommandBufferAllocator,
auto::{Resource, ResourceUseRef2}, auto::{Resource, ResourceUseRef2},
sys::UnsafeCommandBufferBuilder, sys::UnsafeCommandBufferBuilder,
AutoCommandBufferBuilder, ResourceInCommand, AutoCommandBufferBuilder, ResourceInCommand,
@ -25,10 +24,7 @@ use smallvec::SmallVec;
use std::{mem::size_of, sync::Arc}; use std::{mem::size_of, sync::Arc};
/// # Commands to do operations on acceleration structures. /// # Commands to do operations on acceleration structures.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Builds or updates an acceleration structure. /// Builds or updates an acceleration structure.
/// ///
/// # Safety /// # Safety
@ -123,7 +119,7 @@ where
self.add_command( self.add_command(
"build_acceleration_structure", "build_acceleration_structure",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.build_acceleration_structure_unchecked(&info, &build_range_infos); out.build_acceleration_structure_unchecked(&info, &build_range_infos);
}, },
); );
@ -255,7 +251,7 @@ where
self.add_command( self.add_command(
"build_acceleration_structure_indirect", "build_acceleration_structure_indirect",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.build_acceleration_structure_indirect_unchecked( out.build_acceleration_structure_indirect_unchecked(
&info, &info,
&indirect_buffer, &indirect_buffer,
@ -344,7 +340,7 @@ where
] ]
.into_iter() .into_iter()
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_acceleration_structure_unchecked(&info); out.copy_acceleration_structure_unchecked(&info);
}, },
); );
@ -428,7 +424,7 @@ where
] ]
.into_iter() .into_iter()
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_acceleration_structure_to_memory_unchecked(&info); out.copy_acceleration_structure_to_memory_unchecked(&info);
}, },
); );
@ -515,7 +511,7 @@ where
] ]
.into_iter() .into_iter()
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_memory_to_acceleration_structure_unchecked(&info); out.copy_memory_to_acceleration_structure_unchecked(&info);
}, },
); );
@ -611,7 +607,7 @@ where
}, },
) )
}).collect(), }).collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.write_acceleration_structures_properties_unchecked( out.write_acceleration_structures_properties_unchecked(
&acceleration_structures, &acceleration_structures,
&query_pool, &query_pool,
@ -798,10 +794,8 @@ fn add_indirect_buffer_resources(
)); ));
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn build_acceleration_structure( pub unsafe fn build_acceleration_structure(
&mut self, &mut self,
info: &AccelerationStructureBuildGeometryInfo, info: &AccelerationStructureBuildGeometryInfo,
@ -1591,6 +1585,7 @@ where
self self
} }
#[inline]
pub unsafe fn build_acceleration_structure_indirect( pub unsafe fn build_acceleration_structure_indirect(
&mut self, &mut self,
info: &AccelerationStructureBuildGeometryInfo, info: &AccelerationStructureBuildGeometryInfo,
@ -2212,6 +2207,7 @@ where
self self
} }
#[inline]
pub unsafe fn copy_acceleration_structure( pub unsafe fn copy_acceleration_structure(
&mut self, &mut self,
info: &CopyAccelerationStructureInfo, info: &CopyAccelerationStructureInfo,
@ -2271,6 +2267,7 @@ where
self self
} }
#[inline]
pub unsafe fn copy_acceleration_structure_to_memory( pub unsafe fn copy_acceleration_structure_to_memory(
&mut self, &mut self,
info: &CopyAccelerationStructureToMemoryInfo, info: &CopyAccelerationStructureToMemoryInfo,
@ -2341,6 +2338,7 @@ where
self self
} }
#[inline]
pub unsafe fn copy_memory_to_acceleration_structure( pub unsafe fn copy_memory_to_acceleration_structure(
&mut self, &mut self,
info: &CopyMemoryToAccelerationStructureInfo, info: &CopyMemoryToAccelerationStructureInfo,
@ -2411,6 +2409,7 @@ where
self self
} }
#[inline]
pub unsafe fn write_acceleration_structures_properties( pub unsafe fn write_acceleration_structures_properties(
&mut self, &mut self,
acceleration_structures: &[Arc<AccelerationStructure>], acceleration_structures: &[Arc<AccelerationStructure>],

View File

@ -1,9 +1,6 @@
use crate::{ use crate::{
buffer::{BufferContents, BufferUsage, IndexBuffer, Subbuffer}, buffer::{BufferContents, BufferUsage, IndexBuffer, Subbuffer},
command_buffer::{ command_buffer::{auto::SetOrPush, sys::UnsafeCommandBufferBuilder, AutoCommandBufferBuilder},
allocator::CommandBufferAllocator, auto::SetOrPush, sys::UnsafeCommandBufferBuilder,
AutoCommandBufferBuilder,
},
descriptor_set::{ descriptor_set::{
layout::{DescriptorBindingFlags, DescriptorSetLayoutCreateFlags, DescriptorType}, layout::{DescriptorBindingFlags, DescriptorSetLayoutCreateFlags, DescriptorType},
DescriptorBindingResources, DescriptorBufferInfo, DescriptorSetResources, DescriptorBindingResources, DescriptorBufferInfo, DescriptorSetResources,
@ -24,10 +21,7 @@ use std::{cmp::min, ffi::c_void, mem::size_of, sync::Arc};
/// # Commands to bind or push state for pipeline execution commands. /// # Commands to bind or push state for pipeline execution commands.
/// ///
/// These commands require a queue with a pipeline type that uses the given state. /// These commands require a queue with a pipeline type that uses the given state.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Binds descriptor sets for future dispatch or draw calls. /// Binds descriptor sets for future dispatch or draw calls.
pub fn bind_descriptor_sets( pub fn bind_descriptor_sets(
&mut self, &mut self,
@ -101,7 +95,7 @@ where
self.add_command( self.add_command(
"bind_descriptor_sets", "bind_descriptor_sets",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.bind_descriptor_sets_unchecked( out.bind_descriptor_sets_unchecked(
pipeline_bind_point, pipeline_bind_point,
&pipeline_layout, &pipeline_layout,
@ -144,7 +138,7 @@ where
self.add_command( self.add_command(
"bind_index_buffer", "bind_index_buffer",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.bind_index_buffer_unchecked(&index_buffer); out.bind_index_buffer_unchecked(&index_buffer);
}, },
); );
@ -180,7 +174,7 @@ where
self.add_command( self.add_command(
"bind_pipeline_compute", "bind_pipeline_compute",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.bind_pipeline_compute_unchecked(&pipeline); out.bind_pipeline_compute_unchecked(&pipeline);
}, },
); );
@ -223,7 +217,7 @@ where
self.add_command( self.add_command(
"bind_pipeline_graphics", "bind_pipeline_graphics",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.bind_pipeline_graphics_unchecked(&pipeline); out.bind_pipeline_graphics_unchecked(&pipeline);
}, },
); );
@ -271,7 +265,7 @@ where
self.add_command( self.add_command(
"bind_vertex_buffers", "bind_vertex_buffers",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.bind_vertex_buffers_unchecked(first_binding, &vertex_buffers); out.bind_vertex_buffers_unchecked(first_binding, &vertex_buffers);
}, },
); );
@ -335,7 +329,7 @@ where
self.add_command( self.add_command(
"push_constants", "push_constants",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.push_constants_unchecked(&pipeline_layout, offset, &push_constants); out.push_constants_unchecked(&pipeline_layout, offset, &push_constants);
}, },
); );
@ -420,7 +414,7 @@ where
self.add_command( self.add_command(
"push_descriptor_set", "push_descriptor_set",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.push_descriptor_set_unchecked( out.push_descriptor_set_unchecked(
pipeline_bind_point, pipeline_bind_point,
&pipeline_layout, &pipeline_layout,
@ -434,10 +428,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn bind_descriptor_sets( pub unsafe fn bind_descriptor_sets(
&mut self, &mut self,
pipeline_bind_point: PipelineBindPoint, pipeline_bind_point: PipelineBindPoint,
@ -708,6 +700,7 @@ where
self self
} }
#[inline]
pub unsafe fn bind_index_buffer( pub unsafe fn bind_index_buffer(
&mut self, &mut self,
index_buffer: &IndexBuffer, index_buffer: &IndexBuffer,
@ -787,6 +780,7 @@ where
self self
} }
#[inline]
pub unsafe fn bind_pipeline_compute( pub unsafe fn bind_pipeline_compute(
&mut self, &mut self,
pipeline: &ComputePipeline, pipeline: &ComputePipeline,
@ -835,6 +829,7 @@ where
self self
} }
#[inline]
pub unsafe fn bind_pipeline_graphics( pub unsafe fn bind_pipeline_graphics(
&mut self, &mut self,
pipeline: &GraphicsPipeline, pipeline: &GraphicsPipeline,
@ -883,6 +878,7 @@ where
self self
} }
#[inline]
pub unsafe fn bind_vertex_buffers( pub unsafe fn bind_vertex_buffers(
&mut self, &mut self,
first_binding: u32, first_binding: u32,
@ -975,6 +971,7 @@ where
self self
} }
#[inline]
pub unsafe fn push_constants<Pc>( pub unsafe fn push_constants<Pc>(
&mut self, &mut self,
pipeline_layout: &PipelineLayout, pipeline_layout: &PipelineLayout,
@ -1132,6 +1129,7 @@ where
self self
} }
#[inline]
pub unsafe fn push_descriptor_set( pub unsafe fn push_descriptor_set(
&mut self, &mut self,
pipeline_bind_point: PipelineBindPoint, pipeline_bind_point: PipelineBindPoint,

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
buffer::{BufferContents, BufferUsage, Subbuffer}, buffer::{BufferContents, BufferUsage, Subbuffer},
command_buffer::{ command_buffer::{
allocator::CommandBufferAllocator, auto::Resource, sys::UnsafeCommandBufferBuilder, auto::Resource, sys::UnsafeCommandBufferBuilder, AutoCommandBufferBuilder,
AutoCommandBufferBuilder, ResourceInCommand, ResourceInCommand,
}, },
device::{Device, DeviceOwned, QueueFlags}, device::{Device, DeviceOwned, QueueFlags},
format::{ClearColorValue, ClearDepthStencilValue, FormatFeatures}, format::{ClearColorValue, ClearDepthStencilValue, FormatFeatures},
@ -15,10 +15,7 @@ use smallvec::{smallvec, SmallVec};
use std::{mem::size_of_val, sync::Arc}; use std::{mem::size_of_val, sync::Arc};
/// # Commands to fill resources with new data. /// # Commands to fill resources with new data.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Clears a color image with a specific value. /// Clears a color image with a specific value.
pub fn clear_color_image( pub fn clear_color_image(
&mut self, &mut self,
@ -77,7 +74,7 @@ where
)] )]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.clear_color_image_unchecked(&clear_info); out.clear_color_image_unchecked(&clear_info);
}, },
); );
@ -143,7 +140,7 @@ where
)] )]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.clear_depth_stencil_image_unchecked(&clear_info); out.clear_depth_stencil_image_unchecked(&clear_info);
}, },
); );
@ -201,7 +198,7 @@ where
)] )]
.into_iter() .into_iter()
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.fill_buffer_unchecked(&dst_buffer, data); out.fill_buffer_unchecked(&dst_buffer, data);
}, },
); );
@ -267,7 +264,7 @@ where
)] )]
.into_iter() .into_iter()
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.update_buffer_unchecked(&dst_buffer, &data); out.update_buffer_unchecked(&dst_buffer, &data);
}, },
); );
@ -276,10 +273,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn clear_color_image( pub unsafe fn clear_color_image(
&mut self, &mut self,
clear_info: &ClearColorImageInfo, clear_info: &ClearColorImageInfo,
@ -351,6 +346,7 @@ where
self self
} }
#[inline]
pub unsafe fn clear_depth_stencil_image( pub unsafe fn clear_depth_stencil_image(
&mut self, &mut self,
clear_info: &ClearDepthStencilImageInfo, clear_info: &ClearDepthStencilImageInfo,
@ -422,6 +418,7 @@ where
self self
} }
#[inline]
pub unsafe fn fill_buffer( pub unsafe fn fill_buffer(
&mut self, &mut self,
dst_buffer: &Subbuffer<[u32]>, dst_buffer: &Subbuffer<[u32]>,
@ -516,6 +513,7 @@ where
self self
} }
#[inline]
pub unsafe fn update_buffer<D>( pub unsafe fn update_buffer<D>(
&mut self, &mut self,
dst_buffer: &Subbuffer<D>, dst_buffer: &Subbuffer<D>,

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
buffer::{BufferUsage, Subbuffer}, buffer::{BufferUsage, Subbuffer},
command_buffer::{ command_buffer::{
allocator::CommandBufferAllocator, auto::Resource, sys::UnsafeCommandBufferBuilder, auto::Resource, sys::UnsafeCommandBufferBuilder, AutoCommandBufferBuilder,
AutoCommandBufferBuilder, ResourceInCommand, ResourceInCommand,
}, },
device::{Device, DeviceOwned, QueueFlags}, device::{Device, DeviceOwned, QueueFlags},
format::{Format, FormatFeatures}, format::{Format, FormatFeatures},
@ -21,10 +21,7 @@ use std::{
}; };
/// # Commands to transfer data between resources. /// # Commands to transfer data between resources.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Copies data from a buffer to another buffer. /// Copies data from a buffer to another buffer.
/// ///
/// # Panics /// # Panics
@ -103,7 +100,7 @@ where
] ]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_buffer_unchecked(&copy_buffer_info); out.copy_buffer_unchecked(&copy_buffer_info);
}, },
); );
@ -206,7 +203,7 @@ where
] ]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_image_unchecked(&copy_image_info); out.copy_image_unchecked(&copy_image_info);
}, },
); );
@ -293,7 +290,7 @@ where
] ]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_buffer_to_image_unchecked(&copy_buffer_to_image_info); out.copy_buffer_to_image_unchecked(&copy_buffer_to_image_info);
}, },
); );
@ -380,7 +377,7 @@ where
] ]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_image_to_buffer_unchecked(&copy_image_to_buffer_info); out.copy_image_to_buffer_unchecked(&copy_image_to_buffer_info);
}, },
); );
@ -493,7 +490,7 @@ where
] ]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.blit_image_unchecked(&blit_image_info); out.blit_image_unchecked(&blit_image_info);
}, },
); );
@ -585,7 +582,7 @@ where
] ]
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.resolve_image_unchecked(&resolve_image_info); out.resolve_image_unchecked(&resolve_image_info);
}, },
); );
@ -594,10 +591,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn copy_buffer( pub unsafe fn copy_buffer(
&mut self, &mut self,
copy_buffer_info: &CopyBufferInfo, copy_buffer_info: &CopyBufferInfo,
@ -713,6 +708,7 @@ where
self self
} }
#[inline]
pub unsafe fn copy_image( pub unsafe fn copy_image(
&mut self, &mut self,
copy_image_info: &CopyImageInfo, copy_image_info: &CopyImageInfo,
@ -1136,6 +1132,7 @@ where
self self
} }
#[inline]
pub unsafe fn copy_buffer_to_image( pub unsafe fn copy_buffer_to_image(
&mut self, &mut self,
copy_buffer_to_image_info: &CopyBufferToImageInfo, copy_buffer_to_image_info: &CopyBufferToImageInfo,
@ -1478,6 +1475,7 @@ where
self self
} }
#[inline]
pub unsafe fn copy_image_to_buffer( pub unsafe fn copy_image_to_buffer(
&mut self, &mut self,
copy_image_to_buffer_info: &CopyImageToBufferInfo, copy_image_to_buffer_info: &CopyImageToBufferInfo,
@ -1799,6 +1797,7 @@ where
self self
} }
#[inline]
pub unsafe fn blit_image( pub unsafe fn blit_image(
&mut self, &mut self,
blit_image_info: &BlitImageInfo, blit_image_info: &BlitImageInfo,
@ -1971,6 +1970,7 @@ where
self self
} }
#[inline]
pub unsafe fn resolve_image( pub unsafe fn resolve_image(
&mut self, &mut self,
resolve_image_info: &ResolveImageInfo, resolve_image_info: &ResolveImageInfo,

View File

@ -1,8 +1,5 @@
use crate::{ use crate::{
command_buffer::{ command_buffer::{sys::UnsafeCommandBufferBuilder, AutoCommandBufferBuilder},
allocator::CommandBufferAllocator, sys::UnsafeCommandBufferBuilder,
AutoCommandBufferBuilder,
},
device::{DeviceOwned, QueueFlags}, device::{DeviceOwned, QueueFlags},
instance::debug::DebugUtilsLabel, instance::debug::DebugUtilsLabel,
Requires, RequiresAllOf, RequiresOneOf, ValidationError, VulkanObject, Requires, RequiresAllOf, RequiresOneOf, ValidationError, VulkanObject,
@ -14,10 +11,7 @@ use std::ffi::CString;
/// These commands all require the [`ext_debug_utils`] extension to be enabled on the instance. /// These commands all require the [`ext_debug_utils`] extension to be enabled on the instance.
/// ///
/// [`ext_debug_utils`]: crate::instance::InstanceExtensions::ext_debug_utils /// [`ext_debug_utils`]: crate::instance::InstanceExtensions::ext_debug_utils
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Opens a command buffer debug label region. /// Opens a command buffer debug label region.
pub fn begin_debug_utils_label( pub fn begin_debug_utils_label(
&mut self, &mut self,
@ -45,7 +39,7 @@ where
self.add_command( self.add_command(
"begin_debug_utils_label", "begin_debug_utils_label",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.begin_debug_utils_label_unchecked(&label_info); out.begin_debug_utils_label_unchecked(&label_info);
}, },
); );
@ -81,7 +75,7 @@ where
self.add_command( self.add_command(
"end_debug_utils_label", "end_debug_utils_label",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.end_debug_utils_label_unchecked(); out.end_debug_utils_label_unchecked();
}, },
); );
@ -116,7 +110,7 @@ where
self.add_command( self.add_command(
"insert_debug_utils_label", "insert_debug_utils_label",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.insert_debug_utils_label_unchecked(&label_info); out.insert_debug_utils_label_unchecked(&label_info);
}, },
); );
@ -125,10 +119,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn begin_debug_utils_label( pub unsafe fn begin_debug_utils_label(
&mut self, &mut self,
label_info: &DebugUtilsLabel, label_info: &DebugUtilsLabel,
@ -197,6 +189,7 @@ where
self self
} }
#[inline]
pub unsafe fn end_debug_utils_label(&mut self) -> Result<&mut Self, Box<ValidationError>> { pub unsafe fn end_debug_utils_label(&mut self) -> Result<&mut Self, Box<ValidationError>> {
self.validate_end_debug_utils_label()?; self.validate_end_debug_utils_label()?;
@ -243,6 +236,7 @@ where
self self
} }
#[inline]
pub unsafe fn insert_debug_utils_label( pub unsafe fn insert_debug_utils_label(
&mut self, &mut self,
label_info: &DebugUtilsLabel, label_info: &DebugUtilsLabel,

View File

@ -1,8 +1,5 @@
use crate::{ use crate::{
command_buffer::{ command_buffer::{sys::UnsafeCommandBufferBuilder, AutoCommandBufferBuilder},
allocator::CommandBufferAllocator, sys::UnsafeCommandBufferBuilder,
AutoCommandBufferBuilder,
},
device::{DeviceOwned, QueueFlags}, device::{DeviceOwned, QueueFlags},
pipeline::{ pipeline::{
graphics::{ graphics::{
@ -22,10 +19,7 @@ use std::ops::RangeInclusive;
/// # Commands to set dynamic state for pipelines. /// # Commands to set dynamic state for pipelines.
/// ///
/// These commands require a queue with a pipeline type that uses the given state. /// These commands require a queue with a pipeline type that uses the given state.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
// Helper function for dynamic state setting. // Helper function for dynamic state setting.
fn validate_graphics_pipeline_fixed_state( fn validate_graphics_pipeline_fixed_state(
&self, &self,
@ -76,7 +70,7 @@ where
self.add_command( self.add_command(
"set_blend_constants", "set_blend_constants",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_blend_constants_unchecked(constants); out.set_blend_constants_unchecked(constants);
}, },
); );
@ -133,7 +127,7 @@ where
self.add_command( self.add_command(
"set_color_write_enable", "set_color_write_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_color_write_enable_unchecked(&enables); out.set_color_write_enable_unchecked(&enables);
}, },
); );
@ -165,7 +159,7 @@ where
self.add_command( self.add_command(
"set_cull_mode", "set_cull_mode",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_cull_mode_unchecked(cull_mode); out.set_cull_mode_unchecked(cull_mode);
}, },
); );
@ -214,7 +208,7 @@ where
self.add_command( self.add_command(
"set_depth_bias", "set_depth_bias",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_depth_bias_unchecked(constant_factor, clamp, slope_factor); out.set_depth_bias_unchecked(constant_factor, clamp, slope_factor);
}, },
); );
@ -246,7 +240,7 @@ where
self.add_command( self.add_command(
"set_depth_bias_enable", "set_depth_bias_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_depth_bias_enable_unchecked(enable); out.set_depth_bias_enable_unchecked(enable);
}, },
); );
@ -281,7 +275,7 @@ where
self.add_command( self.add_command(
"set_depth_bounds", "set_depth_bounds",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_depth_bounds_unchecked(bounds.clone()); out.set_depth_bounds_unchecked(bounds.clone());
}, },
); );
@ -316,7 +310,7 @@ where
self.add_command( self.add_command(
"set_depth_bounds_test_enable", "set_depth_bounds_test_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_depth_bounds_test_enable_unchecked(enable); out.set_depth_bounds_test_enable_unchecked(enable);
}, },
); );
@ -351,7 +345,7 @@ where
self.add_command( self.add_command(
"set_depth_compare_op", "set_depth_compare_op",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_depth_compare_op_unchecked(compare_op); out.set_depth_compare_op_unchecked(compare_op);
}, },
); );
@ -383,7 +377,7 @@ where
self.add_command( self.add_command(
"set_depth_test_enable", "set_depth_test_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_depth_test_enable_unchecked(enable); out.set_depth_test_enable_unchecked(enable);
}, },
); );
@ -415,7 +409,7 @@ where
self.add_command( self.add_command(
"set_depth_write_enable", "set_depth_write_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_depth_write_enable_unchecked(enable); out.set_depth_write_enable_unchecked(enable);
}, },
); );
@ -461,7 +455,7 @@ where
self.add_command( self.add_command(
"set_discard_rectangle", "set_discard_rectangle",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_discard_rectangle_unchecked(first_rectangle, &rectangles); out.set_discard_rectangle_unchecked(first_rectangle, &rectangles);
}, },
); );
@ -490,7 +484,7 @@ where
self.add_command( self.add_command(
"set_front_face", "set_front_face",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_front_face_unchecked(face); out.set_front_face_unchecked(face);
}, },
); );
@ -527,7 +521,7 @@ where
self.add_command( self.add_command(
"set_line_stipple", "set_line_stipple",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_line_stipple_unchecked(factor, pattern); out.set_line_stipple_unchecked(factor, pattern);
}, },
); );
@ -556,7 +550,7 @@ where
self.add_command( self.add_command(
"set_line_width", "set_line_width",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_line_width_unchecked(line_width); out.set_line_width_unchecked(line_width);
}, },
); );
@ -585,7 +579,7 @@ where
self.add_command( self.add_command(
"set_logic_op", "set_logic_op",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_logic_op_unchecked(logic_op); out.set_logic_op_unchecked(logic_op);
}, },
); );
@ -617,7 +611,7 @@ where
self.add_command( self.add_command(
"set_patch_control_points", "set_patch_control_points",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_patch_control_points_unchecked(num); out.set_patch_control_points_unchecked(num);
}, },
); );
@ -652,7 +646,7 @@ where
self.add_command( self.add_command(
"set_primitive_restart_enable", "set_primitive_restart_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_primitive_restart_enable_unchecked(enable); out.set_primitive_restart_enable_unchecked(enable);
}, },
); );
@ -690,7 +684,7 @@ where
self.add_command( self.add_command(
"set_primitive_topology", "set_primitive_topology",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_primitive_topology_unchecked(topology); out.set_primitive_topology_unchecked(topology);
}, },
); );
@ -725,7 +719,7 @@ where
self.add_command( self.add_command(
"set_rasterizer_discard_enable", "set_rasterizer_discard_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_rasterizer_discard_enable_unchecked(enable); out.set_rasterizer_discard_enable_unchecked(enable);
}, },
); );
@ -772,7 +766,7 @@ where
self.add_command( self.add_command(
"set_scissor", "set_scissor",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_scissor_unchecked(first_scissor, &scissors); out.set_scissor_unchecked(first_scissor, &scissors);
}, },
); );
@ -810,7 +804,7 @@ where
self.add_command( self.add_command(
"set_scissor_with_count", "set_scissor_with_count",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_scissor_with_count_unchecked(&scissors); out.set_scissor_with_count_unchecked(&scissors);
}, },
); );
@ -861,7 +855,7 @@ where
self.add_command( self.add_command(
"set_stencil_compare_mask", "set_stencil_compare_mask",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_stencil_compare_mask_unchecked(faces, compare_mask); out.set_stencil_compare_mask_unchecked(faces, compare_mask);
}, },
); );
@ -933,7 +927,7 @@ where
self.add_command( self.add_command(
"set_stencil_op", "set_stencil_op",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_stencil_op_unchecked(faces, fail_op, pass_op, depth_fail_op, compare_op); out.set_stencil_op_unchecked(faces, fail_op, pass_op, depth_fail_op, compare_op);
}, },
); );
@ -984,7 +978,7 @@ where
self.add_command( self.add_command(
"set_stencil_reference", "set_stencil_reference",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_stencil_reference_unchecked(faces, reference); out.set_stencil_reference_unchecked(faces, reference);
}, },
); );
@ -1016,7 +1010,7 @@ where
self.add_command( self.add_command(
"set_stencil_test_enable", "set_stencil_test_enable",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_stencil_test_enable_unchecked(enable); out.set_stencil_test_enable_unchecked(enable);
}, },
); );
@ -1067,7 +1061,7 @@ where
self.add_command( self.add_command(
"set_stencil_write_mask", "set_stencil_write_mask",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_stencil_write_mask_unchecked(faces, write_mask); out.set_stencil_write_mask_unchecked(faces, write_mask);
}, },
); );
@ -1113,7 +1107,7 @@ where
self.add_command( self.add_command(
"set_viewport", "set_viewport",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_viewport_unchecked(first_viewport, &viewports); out.set_viewport_unchecked(first_viewport, &viewports);
}, },
); );
@ -1151,7 +1145,7 @@ where
self.add_command( self.add_command(
"set_viewport", "set_viewport",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.set_viewport_with_count_unchecked(&viewports); out.set_viewport_with_count_unchecked(&viewports);
}, },
); );
@ -1160,10 +1154,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn set_blend_constants( pub unsafe fn set_blend_constants(
&mut self, &mut self,
constants: [f32; 4], constants: [f32; 4],
@ -1202,6 +1194,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_color_write_enable( pub unsafe fn set_color_write_enable(
&mut self, &mut self,
enables: &[bool], enables: &[bool],
@ -1264,6 +1257,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_cull_mode( pub unsafe fn set_cull_mode(
&mut self, &mut self,
cull_mode: CullMode, cull_mode: CullMode,
@ -1322,6 +1316,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_depth_bias( pub unsafe fn set_depth_bias(
&mut self, &mut self,
constant_factor: f32, constant_factor: f32,
@ -1380,6 +1375,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_depth_bias_enable( pub unsafe fn set_depth_bias_enable(
&mut self, &mut self,
enable: bool, enable: bool,
@ -1434,6 +1430,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_depth_bounds( pub unsafe fn set_depth_bounds(
&mut self, &mut self,
bounds: RangeInclusive<f32>, bounds: RangeInclusive<f32>,
@ -1500,6 +1497,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_depth_bounds_test_enable( pub unsafe fn set_depth_bounds_test_enable(
&mut self, &mut self,
enable: bool, enable: bool,
@ -1557,6 +1555,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_depth_compare_op( pub unsafe fn set_depth_compare_op(
&mut self, &mut self,
compare_op: CompareOp, compare_op: CompareOp,
@ -1621,6 +1620,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_depth_test_enable( pub unsafe fn set_depth_test_enable(
&mut self, &mut self,
enable: bool, enable: bool,
@ -1677,6 +1677,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_depth_write_enable( pub unsafe fn set_depth_write_enable(
&mut self, &mut self,
enable: bool, enable: bool,
@ -1731,6 +1732,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_discard_rectangle( pub unsafe fn set_discard_rectangle(
&mut self, &mut self,
first_rectangle: u32, first_rectangle: u32,
@ -1809,6 +1811,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_front_face( pub unsafe fn set_front_face(
&mut self, &mut self,
face: FrontFace, face: FrontFace,
@ -1867,6 +1870,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_line_stipple( pub unsafe fn set_line_stipple(
&mut self, &mut self,
factor: u32, factor: u32,
@ -1925,6 +1929,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_line_width( pub unsafe fn set_line_width(
&mut self, &mut self,
line_width: f32, line_width: f32,
@ -1971,6 +1976,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_logic_op( pub unsafe fn set_logic_op(
&mut self, &mut self,
logic_op: LogicOp, logic_op: LogicOp,
@ -2025,6 +2031,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_patch_control_points( pub unsafe fn set_patch_control_points(
&mut self, &mut self,
num: u32, num: u32,
@ -2095,6 +2102,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_primitive_restart_enable( pub unsafe fn set_primitive_restart_enable(
&mut self, &mut self,
enable: bool, enable: bool,
@ -2152,6 +2160,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_primitive_topology( pub unsafe fn set_primitive_topology(
&mut self, &mut self,
topology: PrimitiveTopology, topology: PrimitiveTopology,
@ -2264,6 +2273,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_rasterizer_discard_enable( pub unsafe fn set_rasterizer_discard_enable(
&mut self, &mut self,
enable: bool, enable: bool,
@ -2321,6 +2331,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_scissor( pub unsafe fn set_scissor(
&mut self, &mut self,
first_scissor: u32, first_scissor: u32,
@ -2413,6 +2424,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_scissor_with_count( pub unsafe fn set_scissor_with_count(
&mut self, &mut self,
scissors: &[Scissor], scissors: &[Scissor],
@ -2507,6 +2519,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_stencil_compare_mask( pub unsafe fn set_stencil_compare_mask(
&mut self, &mut self,
faces: StencilFaces, faces: StencilFaces,
@ -2556,6 +2569,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_stencil_op( pub unsafe fn set_stencil_op(
&mut self, &mut self,
faces: StencilFaces, faces: StencilFaces,
@ -2668,6 +2682,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_stencil_reference( pub unsafe fn set_stencil_reference(
&mut self, &mut self,
faces: StencilFaces, faces: StencilFaces,
@ -2717,6 +2732,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_stencil_test_enable( pub unsafe fn set_stencil_test_enable(
&mut self, &mut self,
enable: bool, enable: bool,
@ -2771,6 +2787,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_stencil_write_mask( pub unsafe fn set_stencil_write_mask(
&mut self, &mut self,
faces: StencilFaces, faces: StencilFaces,
@ -2820,6 +2837,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_viewport( pub unsafe fn set_viewport(
&mut self, &mut self,
first_viewport: u32, first_viewport: u32,
@ -2912,6 +2930,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_viewport_with_count( pub unsafe fn set_viewport_with_count(
&mut self, &mut self,
viewports: &[Viewport], viewports: &[Viewport],

View File

@ -2,7 +2,6 @@ use crate::{
acceleration_structure::AccelerationStructure, acceleration_structure::AccelerationStructure,
buffer::{view::BufferView, BufferUsage, Subbuffer}, buffer::{view::BufferView, BufferUsage, Subbuffer},
command_buffer::{ command_buffer::{
allocator::CommandBufferAllocator,
auto::{RenderPassState, RenderPassStateType, Resource, ResourceUseRef2}, auto::{RenderPassState, RenderPassStateType, Resource, ResourceUseRef2},
sys::UnsafeCommandBufferBuilder, sys::UnsafeCommandBufferBuilder,
AutoCommandBufferBuilder, DispatchIndirectCommand, DrawIndexedIndirectCommand, AutoCommandBufferBuilder, DispatchIndirectCommand, DrawIndexedIndirectCommand,
@ -44,10 +43,7 @@ macro_rules! vuids {
/// # Commands to execute a bound pipeline. /// # Commands to execute a bound pipeline.
/// ///
/// Dispatch commands require a compute queue, draw commands require a graphics queue. /// Dispatch commands require a compute queue, draw commands require a graphics queue.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Perform a single compute operation using a compute pipeline. /// Perform a single compute operation using a compute pipeline.
/// ///
/// A compute pipeline must have been bound using /// A compute pipeline must have been bound using
@ -105,7 +101,7 @@ where
self.add_command( self.add_command(
"dispatch", "dispatch",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.dispatch_unchecked(group_counts); out.dispatch_unchecked(group_counts);
}, },
); );
@ -181,7 +177,7 @@ where
self.add_command( self.add_command(
"dispatch", "dispatch",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.dispatch_indirect_unchecked(&indirect_buffer); out.dispatch_indirect_unchecked(&indirect_buffer);
}, },
); );
@ -358,7 +354,7 @@ where
self.add_command( self.add_command(
"draw", "draw",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.draw_unchecked(vertex_count, instance_count, first_vertex, first_instance); out.draw_unchecked(vertex_count, instance_count, first_vertex, first_instance);
}, },
); );
@ -460,7 +456,7 @@ where
self.add_command( self.add_command(
"draw_indirect", "draw_indirect",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.draw_indirect_unchecked(&indirect_buffer, draw_count, stride); out.draw_indirect_unchecked(&indirect_buffer, draw_count, stride);
}, },
); );
@ -675,7 +671,7 @@ where
self.add_command( self.add_command(
"draw_indexed", "draw_indexed",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.draw_indexed_unchecked( out.draw_indexed_unchecked(
index_count, index_count,
instance_count, instance_count,
@ -797,7 +793,7 @@ where
self.add_command( self.add_command(
"draw_indexed_indirect", "draw_indexed_indirect",
used_resources, used_resources,
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.draw_indexed_indirect_unchecked(&indirect_buffer, draw_count, stride); out.draw_indexed_indirect_unchecked(&indirect_buffer, draw_count, stride);
}, },
); );
@ -2711,10 +2707,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn dispatch( pub unsafe fn dispatch(
&mut self, &mut self,
group_counts: [u32; 3], group_counts: [u32; 3],
@ -2784,6 +2778,7 @@ where
self self
} }
#[inline]
pub unsafe fn dispatch_indirect( pub unsafe fn dispatch_indirect(
&mut self, &mut self,
indirect_buffer: &Subbuffer<[DispatchIndirectCommand]>, indirect_buffer: &Subbuffer<[DispatchIndirectCommand]>,
@ -2858,6 +2853,7 @@ where
self self
} }
#[inline]
pub unsafe fn draw( pub unsafe fn draw(
&mut self, &mut self,
vertex_count: u32, vertex_count: u32,
@ -2914,6 +2910,7 @@ where
self self
} }
#[inline]
pub unsafe fn draw_indirect( pub unsafe fn draw_indirect(
&mut self, &mut self,
indirect_buffer: &Subbuffer<[DrawIndirectCommand]>, indirect_buffer: &Subbuffer<[DrawIndirectCommand]>,
@ -3048,6 +3045,7 @@ where
self self
} }
#[inline]
pub unsafe fn draw_indexed( pub unsafe fn draw_indexed(
&mut self, &mut self,
index_count: u32, index_count: u32,
@ -3120,6 +3118,7 @@ where
self self
} }
#[inline]
pub unsafe fn draw_indexed_indirect( pub unsafe fn draw_indexed_indirect(
&mut self, &mut self,
indirect_buffer: &Subbuffer<[DrawIndexedIndirectCommand]>, indirect_buffer: &Subbuffer<[DrawIndexedIndirectCommand]>,

View File

@ -1,7 +1,6 @@
use crate::{ use crate::{
buffer::{BufferUsage, Subbuffer}, buffer::{BufferUsage, Subbuffer},
command_buffer::{ command_buffer::{
allocator::CommandBufferAllocator,
auto::{QueryState, Resource}, auto::{QueryState, Resource},
sys::UnsafeCommandBufferBuilder, sys::UnsafeCommandBufferBuilder,
AutoCommandBufferBuilder, ResourceInCommand, AutoCommandBufferBuilder, ResourceInCommand,
@ -14,10 +13,7 @@ use crate::{
use std::{ops::Range, sync::Arc}; use std::{ops::Range, sync::Arc};
/// # Commands related to queries. /// # Commands related to queries.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Begins a query. /// Begins a query.
/// ///
/// The query will be active until [`end_query`](Self::end_query) is called for the same query. /// The query will be active until [`end_query`](Self::end_query) is called for the same query.
@ -101,7 +97,7 @@ where
self.add_command( self.add_command(
"begin_query", "begin_query",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.begin_query_unchecked(&query_pool, query, flags); out.begin_query_unchecked(&query_pool, query, flags);
}, },
); );
@ -173,7 +169,7 @@ where
self.add_command( self.add_command(
"end_query", "end_query",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.end_query_unchecked(&query_pool, query); out.end_query_unchecked(&query_pool, query);
}, },
); );
@ -240,7 +236,7 @@ where
self.add_command( self.add_command(
"write_timestamp", "write_timestamp",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.write_timestamp_unchecked(&query_pool, query, stage); out.write_timestamp_unchecked(&query_pool, query, stage);
}, },
); );
@ -323,7 +319,7 @@ where
)] )]
.into_iter() .into_iter()
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.copy_query_pool_results_unchecked( out.copy_query_pool_results_unchecked(
&query_pool, &query_pool,
queries.clone(), queries.clone(),
@ -395,7 +391,7 @@ where
self.add_command( self.add_command(
"reset_query_pool", "reset_query_pool",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.reset_query_pool_unchecked(&query_pool, queries.clone()); out.reset_query_pool_unchecked(&query_pool, queries.clone());
}, },
); );
@ -404,10 +400,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn begin_query( pub unsafe fn begin_query(
&mut self, &mut self,
query_pool: &QueryPool, query_pool: &QueryPool,
@ -568,6 +562,7 @@ where
self self
} }
#[inline]
pub unsafe fn end_query( pub unsafe fn end_query(
&mut self, &mut self,
query_pool: &QueryPool, query_pool: &QueryPool,
@ -624,6 +619,7 @@ where
self self
} }
#[inline]
pub unsafe fn write_timestamp( pub unsafe fn write_timestamp(
&mut self, &mut self,
query_pool: &QueryPool, query_pool: &QueryPool,
@ -883,6 +879,7 @@ where
self self
} }
#[inline]
pub unsafe fn copy_query_pool_results<T>( pub unsafe fn copy_query_pool_results<T>(
&mut self, &mut self,
query_pool: &QueryPool, query_pool: &QueryPool,
@ -1023,6 +1020,7 @@ where
self self
} }
#[inline]
pub unsafe fn reset_query_pool( pub unsafe fn reset_query_pool(
&mut self, &mut self,
query_pool: &QueryPool, query_pool: &QueryPool,

View File

@ -1,6 +1,5 @@
use crate::{ use crate::{
command_buffer::{ command_buffer::{
allocator::CommandBufferAllocator,
auto::{ auto::{
BeginRenderPassState, BeginRenderingState, RenderPassState, RenderPassStateAttachments, BeginRenderPassState, BeginRenderingState, RenderPassState, RenderPassStateAttachments,
RenderPassStateType, Resource, RenderPassStateType, Resource,
@ -25,10 +24,7 @@ use std::{cmp::min, ops::Range, sync::Arc};
/// # Commands for render passes. /// # Commands for render passes.
/// ///
/// These commands require a graphics queue. /// These commands require a graphics queue.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Begins a render pass using a render pass object and framebuffer. /// Begins a render pass using a render pass object and framebuffer.
/// ///
/// You must call this or `begin_rendering` before you can record draw commands. /// You must call this or `begin_rendering` before you can record draw commands.
@ -140,7 +136,7 @@ where
) )
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.begin_render_pass_unchecked(&render_pass_begin_info, &subpass_begin_info); out.begin_render_pass_unchecked(&render_pass_begin_info, &subpass_begin_info);
}, },
); );
@ -242,7 +238,7 @@ where
self.add_command( self.add_command(
"next_subpass", "next_subpass",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.next_subpass_unchecked(&subpass_end_info, &subpass_begin_info); out.next_subpass_unchecked(&subpass_end_info, &subpass_begin_info);
}, },
); );
@ -323,7 +319,7 @@ where
self.add_render_pass_end( self.add_render_pass_end(
"end_render_pass", "end_render_pass",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.end_render_pass_unchecked(&subpass_end_info); out.end_render_pass_unchecked(&subpass_end_info);
}, },
); );
@ -332,10 +328,7 @@ where
} }
} }
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Begins a render pass without a render pass object or framebuffer. /// Begins a render pass without a render pass object or framebuffer.
/// ///
/// You must call this or `begin_render_pass` before you can record draw commands. /// You must call this or `begin_render_pass` before you can record draw commands.
@ -564,7 +557,7 @@ where
.flatten() .flatten()
})) }))
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.begin_rendering_unchecked(&rendering_info); out.begin_rendering_unchecked(&rendering_info);
}, },
); );
@ -631,7 +624,7 @@ where
self.add_render_pass_end( self.add_render_pass_end(
"end_rendering", "end_rendering",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.end_rendering_unchecked(); out.end_rendering_unchecked();
}, },
); );
@ -882,7 +875,7 @@ where
self.add_command( self.add_command(
"clear_attachments", "clear_attachments",
Default::default(), Default::default(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.clear_attachments_unchecked(&attachments, &rects); out.clear_attachments_unchecked(&attachments, &rects);
}, },
); );
@ -891,10 +884,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn begin_render_pass( pub unsafe fn begin_render_pass(
&mut self, &mut self,
render_pass_begin_info: &RenderPassBeginInfo, render_pass_begin_info: &RenderPassBeginInfo,
@ -1315,6 +1306,7 @@ where
self self
} }
#[inline]
pub unsafe fn next_subpass( pub unsafe fn next_subpass(
&mut self, &mut self,
subpass_end_info: &SubpassEndInfo, subpass_end_info: &SubpassEndInfo,
@ -1408,6 +1400,7 @@ where
self self
} }
#[inline]
pub unsafe fn end_render_pass( pub unsafe fn end_render_pass(
&mut self, &mut self,
subpass_end_info: &SubpassEndInfo, subpass_end_info: &SubpassEndInfo,
@ -1481,6 +1474,7 @@ where
self self
} }
#[inline]
pub unsafe fn begin_rendering( pub unsafe fn begin_rendering(
&mut self, &mut self,
rendering_info: &RenderingInfo, rendering_info: &RenderingInfo,
@ -1653,6 +1647,7 @@ where
self self
} }
#[inline]
pub unsafe fn end_rendering(&mut self) -> Result<&mut Self, Box<ValidationError>> { pub unsafe fn end_rendering(&mut self) -> Result<&mut Self, Box<ValidationError>> {
self.validate_end_rendering()?; self.validate_end_rendering()?;
@ -1690,6 +1685,7 @@ where
self self
} }
#[inline]
pub unsafe fn clear_attachments( pub unsafe fn clear_attachments(
&mut self, &mut self,
attachments: &[ClearAttachment], attachments: &[ClearAttachment],

View File

@ -1,6 +1,5 @@
use crate::{ use crate::{
command_buffer::{ command_buffer::{
allocator::CommandBufferAllocator,
auto::{RenderPassStateType, Resource, ResourceUseRef2}, auto::{RenderPassStateType, Resource, ResourceUseRef2},
sys::UnsafeCommandBufferBuilder, sys::UnsafeCommandBufferBuilder,
AutoCommandBufferBuilder, CommandBufferInheritanceRenderPassType, CommandBufferLevel, AutoCommandBufferBuilder, CommandBufferInheritanceRenderPassType, CommandBufferLevel,
@ -18,10 +17,7 @@ use std::{cmp::min, iter, ops::Deref, sync::Arc};
/// ///
/// These commands can be called on any queue that can execute the commands recorded in the /// These commands can be called on any queue that can execute the commands recorded in the
/// secondary command buffer. /// secondary command buffer.
impl<L, A> AutoCommandBufferBuilder<L, A> impl<L> AutoCommandBufferBuilder<L> {
where
A: CommandBufferAllocator,
{
/// Executes a secondary command buffer. /// Executes a secondary command buffer.
/// ///
/// If the `flags` that `command_buffer` was created with are more restrictive than those of /// If the `flags` that `command_buffer` was created with are more restrictive than those of
@ -543,7 +539,7 @@ where
})) }))
}) })
.collect(), .collect(),
move |out: &mut UnsafeCommandBufferBuilder<A>| { move |out: &mut UnsafeCommandBufferBuilder| {
out.execute_commands_locked(&command_buffers); out.execute_commands_locked(&command_buffers);
}, },
); );
@ -552,10 +548,8 @@ where
} }
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn execute_commands( pub unsafe fn execute_commands(
&mut self, &mut self,
command_buffers: &[Arc<dyn SecondaryCommandBufferAbstract>], command_buffers: &[Arc<dyn SecondaryCommandBufferAbstract>],

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
command_buffer::{allocator::CommandBufferAllocator, sys::UnsafeCommandBufferBuilder}, command_buffer::sys::UnsafeCommandBufferBuilder,
device::{DeviceOwned, QueueFlags}, device::{DeviceOwned, QueueFlags},
sync::{ sync::{
event::Event, BufferMemoryBarrier, DependencyFlags, DependencyInfo, ImageMemoryBarrier, event::Event, BufferMemoryBarrier, DependencyFlags, DependencyInfo, ImageMemoryBarrier,
@ -10,10 +10,8 @@ use crate::{
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ptr, sync::Arc}; use std::{ptr, sync::Arc};
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator,
{
pub unsafe fn pipeline_barrier( pub unsafe fn pipeline_barrier(
&mut self, &mut self,
dependency_info: &DependencyInfo, dependency_info: &DependencyInfo,
@ -454,6 +452,7 @@ where
self self
} }
#[inline]
pub unsafe fn set_event( pub unsafe fn set_event(
&mut self, &mut self,
event: &Event, event: &Event,
@ -808,6 +807,7 @@ where
self self
} }
#[inline]
pub unsafe fn wait_events( pub unsafe fn wait_events(
&mut self, &mut self,
events: &[(Arc<Event>, DependencyInfo)], events: &[(Arc<Event>, DependencyInfo)],
@ -1315,6 +1315,7 @@ where
self self
} }
#[inline]
pub unsafe fn reset_event( pub unsafe fn reset_event(
&mut self, &mut self,
event: &Event, event: &Event,

View File

@ -58,38 +58,38 @@
//! the moment when the execution will end on the GPU. //! the moment when the execution will end on the GPU.
//! //!
//! ``` //! ```
//! use vulkano::command_buffer::AutoCommandBufferBuilder; //! use vulkano::command_buffer::{
//! use vulkano::command_buffer::CommandBufferUsage; //! AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract,
//! use vulkano::command_buffer::PrimaryCommandBufferAbstract; //! SubpassContents,
//! use vulkano::command_buffer::SubpassContents; //! };
//! //!
//! # use vulkano::{buffer::BufferContents, pipeline::graphics::vertex_input::Vertex};
//!
//! # #[derive(BufferContents, Vertex)]
//! # #[repr(C)]
//! # struct PosVertex {
//! # #[format(R32G32B32_SFLOAT)]
//! # position: [f32; 3]
//! # };
//! # let device: std::sync::Arc<vulkano::device::Device> = return; //! # let device: std::sync::Arc<vulkano::device::Device> = return;
//! # let queue: std::sync::Arc<vulkano::device::Queue> = return; //! # let queue: std::sync::Arc<vulkano::device::Queue> = return;
//! # let vertex_buffer: vulkano::buffer::Subbuffer<[PosVertex]> = return; //! # let vertex_buffer: vulkano::buffer::Subbuffer<[u32]> = return;
//! # let render_pass_begin_info: vulkano::command_buffer::RenderPassBeginInfo = return; //! # let render_pass_begin_info: vulkano::command_buffer::RenderPassBeginInfo = return;
//! # let graphics_pipeline: std::sync::Arc<vulkano::pipeline::graphics::GraphicsPipeline> = return; //! # let graphics_pipeline: std::sync::Arc<vulkano::pipeline::graphics::GraphicsPipeline> = return;
//! # let command_buffer_allocator: vulkano::command_buffer::allocator::StandardCommandBufferAllocator = return; //! # let command_buffer_allocator: std::sync::Arc<vulkano::command_buffer::allocator::StandardCommandBufferAllocator> = return;
//! #
//! let cb = AutoCommandBufferBuilder::primary( //! let cb = AutoCommandBufferBuilder::primary(
//! &command_buffer_allocator, //! command_buffer_allocator.clone(),
//! queue.queue_family_index(), //! queue.queue_family_index(),
//! CommandBufferUsage::MultipleSubmit //! CommandBufferUsage::MultipleSubmit,
//! ).unwrap() //! )
//! .begin_render_pass(render_pass_begin_info, Default::default()).unwrap() //! .unwrap()
//! .bind_pipeline_graphics(graphics_pipeline.clone()).unwrap() //! .begin_render_pass(render_pass_begin_info, Default::default())
//! .bind_vertex_buffers(0, vertex_buffer.clone()).unwrap() //! .unwrap()
//! .draw(vertex_buffer.len() as u32, 1, 0, 0).unwrap() //! .bind_pipeline_graphics(graphics_pipeline.clone())
//! .end_render_pass(Default::default()).unwrap() //! .unwrap()
//! .build().unwrap(); //! .bind_vertex_buffers(0, vertex_buffer.clone())
//! .unwrap()
//! .draw(vertex_buffer.len() as u32, 1, 0, 0)
//! .unwrap()
//! .end_render_pass(Default::default())
//! .unwrap()
//! .build()
//! .unwrap();
//! //!
//! let _future = cb.execute(queue.clone()); //! let future = cb.execute(queue.clone());
//! ``` //! ```
//! //!
//! [`StandardCommandBufferAllocator`]: self::allocator::StandardCommandBufferAllocator //! [`StandardCommandBufferAllocator`]: self::allocator::StandardCommandBufferAllocator

View File

@ -1,8 +1,5 @@
use super::{ use super::{
allocator::{ allocator::{CommandBufferAlloc, CommandBufferAllocator},
CommandBufferAlloc, CommandBufferAllocator, CommandBufferBuilderAlloc,
StandardCommandBufferAllocator,
},
CommandBufferInheritanceInfo, CommandBufferLevel, CommandBufferUsage, CommandBufferInheritanceInfo, CommandBufferLevel, CommandBufferUsage,
}; };
use crate::{ use crate::{
@ -12,10 +9,10 @@ use crate::{
}, },
device::{Device, DeviceOwned, QueueFamilyProperties}, device::{Device, DeviceOwned, QueueFamilyProperties},
query::QueryControlFlags, query::QueryControlFlags,
ValidationError, VulkanError, VulkanObject, Validated, ValidationError, VulkanError, VulkanObject,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{fmt::Debug, ptr, sync::Arc}; use std::{fmt::Debug, mem::ManuallyDrop, ptr, sync::Arc};
/// Command buffer being built. /// Command buffer being built.
/// ///
@ -24,22 +21,16 @@ use std::{fmt::Debug, ptr, sync::Arc};
/// - All submitted commands must be valid and follow the requirements of the Vulkan specification. /// - All submitted commands must be valid and follow the requirements of the Vulkan specification.
/// - Any resources used by submitted commands must outlive the returned builder and its created /// - Any resources used by submitted commands must outlive the returned builder and its created
/// command buffer. They must be protected against data races through manual synchronization. /// command buffer. They must be protected against data races through manual synchronization.
pub struct UnsafeCommandBufferBuilder<A = StandardCommandBufferAllocator> pub struct UnsafeCommandBufferBuilder {
where allocation: ManuallyDrop<CommandBufferAlloc>,
A: CommandBufferAllocator, allocator: Arc<dyn CommandBufferAllocator>,
{
builder_alloc: A::Builder,
queue_family_index: u32, queue_family_index: u32,
// Must be `None` in a primary command buffer and `Some` in a secondary command buffer. // Must be `None` in a primary command buffer and `Some` in a secondary command buffer.
inheritance_info: Option<CommandBufferInheritanceInfo>, inheritance_info: Option<CommandBufferInheritanceInfo>,
pub(super) usage: CommandBufferUsage, pub(super) usage: CommandBufferUsage,
} }
impl<A> UnsafeCommandBufferBuilder<A> impl UnsafeCommandBufferBuilder {
where
A: CommandBufferAllocator,
{
/// Creates a new builder, for recording commands. /// Creates a new builder, for recording commands.
/// ///
/// # Safety /// # Safety
@ -47,15 +38,12 @@ where
/// - `begin_info` must be valid. /// - `begin_info` must be valid.
#[inline] #[inline]
pub unsafe fn new( pub unsafe fn new(
allocator: &A, allocator: Arc<dyn CommandBufferAllocator>,
queue_family_index: u32, queue_family_index: u32,
level: CommandBufferLevel, level: CommandBufferLevel,
begin_info: CommandBufferBeginInfo, begin_info: CommandBufferBeginInfo,
) -> Result<Self, VulkanError> { ) -> Result<Self, Validated<VulkanError>> {
let builder_alloc = allocator let allocation = allocator.allocate(queue_family_index, level)?;
.allocate(queue_family_index, level, 1)?
.next()
.expect("requested one command buffer from the command pool, but got zero");
let CommandBufferBeginInfo { let CommandBufferBeginInfo {
usage, usage,
@ -161,14 +149,15 @@ where
..Default::default() ..Default::default()
}; };
let fns = builder_alloc.device().fns(); let fns = allocation.inner.device().fns();
(fns.v1_0.begin_command_buffer)(builder_alloc.inner().handle(), &begin_info_vk) (fns.v1_0.begin_command_buffer)(allocation.inner.handle(), &begin_info_vk)
.result() .result()
.map_err(VulkanError::from)?; .map_err(VulkanError::from)?;
} }
Ok(UnsafeCommandBufferBuilder { Ok(UnsafeCommandBufferBuilder {
builder_alloc, allocation: ManuallyDrop::new(allocation),
allocator,
inheritance_info, inheritance_info,
queue_family_index, queue_family_index,
usage, usage,
@ -177,20 +166,15 @@ where
/// Turns the builder into an actual command buffer. /// Turns the builder into an actual command buffer.
#[inline] #[inline]
pub fn build(self) -> Result<UnsafeCommandBuffer<A>, VulkanError> { pub fn build(self) -> Result<UnsafeCommandBuffer, VulkanError> {
unsafe { unsafe {
let fns = self.device().fns(); let fns = self.device().fns();
(fns.v1_0.end_command_buffer)(self.handle()) (fns.v1_0.end_command_buffer)(self.handle())
.result() .result()
.map_err(VulkanError::from)?; .map_err(VulkanError::from)?;
Ok(UnsafeCommandBuffer {
alloc: self.builder_alloc.into_alloc(),
inheritance_info: self.inheritance_info,
queue_family_index: self.queue_family_index,
usage: self.usage,
})
} }
Ok(UnsafeCommandBuffer { inner: self })
} }
/// Returns the queue family index that this command buffer was created for. /// Returns the queue family index that this command buffer was created for.
@ -202,7 +186,7 @@ where
/// Returns the level of the command buffer. /// Returns the level of the command buffer.
#[inline] #[inline]
pub fn level(&self) -> CommandBufferLevel { pub fn level(&self) -> CommandBufferLevel {
self.builder_alloc.inner().level() self.allocation.inner.level()
} }
/// Returns the usage that the command buffer was created with. /// Returns the usage that the command buffer was created with.
@ -222,32 +206,31 @@ where
} }
} }
unsafe impl<A> VulkanObject for UnsafeCommandBufferBuilder<A> impl Drop for UnsafeCommandBufferBuilder {
where #[inline]
A: CommandBufferAllocator, fn drop(&mut self) {
{ let allocation = unsafe { ManuallyDrop::take(&mut self.allocation) };
unsafe { self.allocator.deallocate(allocation) };
}
}
unsafe impl VulkanObject for UnsafeCommandBufferBuilder {
type Handle = ash::vk::CommandBuffer; type Handle = ash::vk::CommandBuffer;
#[inline] #[inline]
fn handle(&self) -> Self::Handle { fn handle(&self) -> Self::Handle {
self.builder_alloc.inner().handle() self.allocation.inner.handle()
} }
} }
unsafe impl<A> DeviceOwned for UnsafeCommandBufferBuilder<A> unsafe impl DeviceOwned for UnsafeCommandBufferBuilder {
where
A: CommandBufferAllocator,
{
#[inline] #[inline]
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
self.builder_alloc.device() self.allocation.inner.device()
} }
} }
impl<A> Debug for UnsafeCommandBufferBuilder<A> impl Debug for UnsafeCommandBufferBuilder {
where
A: CommandBufferAllocator,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("UnsafeCommandBufferBuilder") f.debug_struct("UnsafeCommandBufferBuilder")
.field("handle", &self.level()) .field("handle", &self.level())
@ -314,65 +297,57 @@ impl CommandBufferBeginInfo {
/// The command buffer must not outlive the command pool that it was created from, /// The command buffer must not outlive the command pool that it was created from,
/// nor the resources used by the recorded commands. /// nor the resources used by the recorded commands.
#[derive(Debug)] #[derive(Debug)]
pub struct UnsafeCommandBuffer<A = StandardCommandBufferAllocator> pub struct UnsafeCommandBuffer {
where inner: UnsafeCommandBufferBuilder,
A: CommandBufferAllocator,
{
alloc: A::Alloc,
queue_family_index: u32,
// Must be `None` in a primary command buffer and `Some` in a secondary command buffer.
inheritance_info: Option<CommandBufferInheritanceInfo>,
usage: CommandBufferUsage,
} }
impl<A> UnsafeCommandBuffer<A> // `UnsafeCommandBufferBuilder` is `!Send + !Sync` so that the implementation of
where // `CommandBufferAllocator::allocate` can assume that a command buffer in the recording state
A: CommandBufferAllocator, // doesn't leave the thread it was allocated on. However, as the safety contract states,
{ // `CommandBufferAllocator::deallocate` must acccount for the possibility that a command buffer is
// moved between threads after the recording is finished, and thus deallocated from another thread.
// That's why this is sound.
unsafe impl Send for UnsafeCommandBuffer {}
unsafe impl Sync for UnsafeCommandBuffer {}
impl UnsafeCommandBuffer {
/// Returns the queue family index that this command buffer was created for. /// Returns the queue family index that this command buffer was created for.
#[inline] #[inline]
pub fn queue_family_index(&self) -> u32 { pub fn queue_family_index(&self) -> u32 {
self.queue_family_index self.inner.queue_family_index
} }
/// Returns the level of the command buffer. /// Returns the level of the command buffer.
#[inline] #[inline]
pub fn level(&self) -> CommandBufferLevel { pub fn level(&self) -> CommandBufferLevel {
self.alloc.inner().level() self.inner.allocation.inner.level()
} }
/// Returns the usage that the command buffer was created with. /// Returns the usage that the command buffer was created with.
#[inline] #[inline]
pub fn usage(&self) -> CommandBufferUsage { pub fn usage(&self) -> CommandBufferUsage {
self.usage self.inner.usage
} }
/// Returns the inheritance info of the command buffer, if it is a secondary command buffer. /// Returns the inheritance info of the command buffer, if it is a secondary command buffer.
#[inline] #[inline]
pub fn inheritance_info(&self) -> Option<&CommandBufferInheritanceInfo> { pub fn inheritance_info(&self) -> Option<&CommandBufferInheritanceInfo> {
self.inheritance_info.as_ref() self.inner.inheritance_info.as_ref()
} }
} }
unsafe impl<A> VulkanObject for UnsafeCommandBuffer<A> unsafe impl VulkanObject for UnsafeCommandBuffer {
where
A: CommandBufferAllocator,
{
type Handle = ash::vk::CommandBuffer; type Handle = ash::vk::CommandBuffer;
#[inline] #[inline]
fn handle(&self) -> Self::Handle { fn handle(&self) -> Self::Handle {
self.alloc.inner().handle() self.inner.allocation.inner.handle()
} }
} }
unsafe impl<A> DeviceOwned for UnsafeCommandBuffer<A> unsafe impl DeviceOwned for UnsafeCommandBuffer {
where
A: CommandBufferAllocator,
{
#[inline] #[inline]
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
self.alloc.device() self.inner.allocation.inner.device()
} }
} }

View File

@ -552,9 +552,12 @@ mod tests {
) )
.unwrap(); .unwrap();
let cb_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
device.clone(),
Default::default(),
));
let mut cbb = AutoCommandBufferBuilder::primary( let mut cbb = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )
@ -696,9 +699,12 @@ mod tests {
) )
.unwrap(); .unwrap();
let cb_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); let cb_allocator = Arc::new(StandardCommandBufferAllocator::new(
device.clone(),
Default::default(),
));
let mut cbb = AutoCommandBufferBuilder::primary( let mut cbb = AutoCommandBufferBuilder::primary(
&cb_allocator, cb_allocator,
queue.queue_family_index(), queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit, CommandBufferUsage::OneTimeSubmit,
) )