Simplify handling of command buffer usage flags (#1563)

This commit is contained in:
Rua 2021-04-26 16:53:18 +02:00 committed by GitHub
parent a83f0fe489
commit 0c1e0ff40d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 401 additions and 542 deletions

View File

@ -3,9 +3,12 @@
Please add new changes at the bottom, preceded by a hyphen -.
Breaking changes should be listed first, before other changes, and should be preceded by - **Breaking**.
-->
- **Breaking** `AutoCommandBuffer` and the `CommandBuffer` trait have been split in two, one for primary and the other for secondary command buffers. `AutoCommandBufferBuilder` remains one type, but has a type parameter for the level of command buffer it will be create, and some of its methods are only implemented for builders that create `PrimaryAutoCommandBuffer`.
- **Breaking** `Kind` has been renamed to `CommandBufferLevel`, and for secondary command buffers it now contains a single `CommandBufferInheritance` value.
- **Breaking** `CommandBufferInheritance::occlusion_query` and `UnsafeCommandBufferBuilder::begin_query` now take `QueryControlFlags` instead of a boolean.
- **Breaking** Changes to command buffers:
- `AutoCommandBuffer` and the `CommandBuffer` trait have been split in two, one for primary and the other for secondary command buffers. `AutoCommandBufferBuilder` remains one type, but has a type parameter for the level of command buffer it will be creating, and some of its methods are only implemented for builders that create `PrimaryAutoCommandBuffer`.
- The `Flags` enum is renamed to `CommandBufferUsage`, and is exported from the main `command_buffer` module. The `None` variant is renamed to `MultipleSubmit`.
- Simplified the number of constructors on `AutoCommandBufferBuilder` by adding a `CommandBufferUsage` parameter.
- `Kind` has been renamed to `CommandBufferLevel`, and for secondary command buffers it now contains a single `CommandBufferInheritance` value.
- `CommandBufferInheritance::occlusion_query` and `UnsafeCommandBufferBuilder::begin_query` now take `QueryControlFlags` instead of a boolean.
- **Breaking** The non-default constructors of `ImageView` have been replaced with a builder, created with `ImageView::start(image)`.
- **Breaking** Added support for component mapping/swizzling on image views.
- `image::Swizzle` is moved and renamed to `image::view::ComponentMapping`. It now has an `is_identity` method.

View File

@ -13,8 +13,9 @@
// been more or more used for general-purpose operations as well. This is called "General-Purpose
// GPU", or *GPGPU*. This is what this example demonstrates.
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano::device::{Device, DeviceExtensions};
@ -23,8 +24,6 @@ use vulkano::pipeline::ComputePipeline;
use vulkano::sync;
use vulkano::sync::GpuFuture;
use std::sync::Arc;
const DEVICE_EXTENSIONS: DeviceExtensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
..DeviceExtensions::none()
@ -135,8 +134,12 @@ fn main() {
);
// In order to execute our operation, we have to build a command buffer.
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
// The command buffer only does one thing: execute the compute pipeline.
// This is called a *dispatch* operation.

View File

@ -19,8 +19,12 @@
// See: https://github.com/vulkano-rs/vulkano/issues/1221
// Finally, I have not profiled CpuBufferPool against CpuAccessibleBuffer
use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use vulkano::buffer::CpuBufferPool;
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageUsage, SwapchainImage};
@ -35,15 +39,11 @@ use vulkano::swapchain::{
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Default, Debug, Clone)]
struct Vertex {
position: [f32; 2],
@ -274,9 +274,10 @@ fn main() {
// Allocate a new chunk from buffer_pool
let buffer = buffer_pool.chunk(data.to_vec()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary_one_time_submit(
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder

View File

@ -9,9 +9,9 @@
use vulkano::buffer::BufferUsage;
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::DynamicState;
use vulkano::command_buffer::SecondaryAutoCommandBuffer;
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SecondaryAutoCommandBuffer,
};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::Queue;
use vulkano::image::ImageViewAbstract;
@ -142,6 +142,7 @@ impl AmbientLightingSystem {
let mut builder = AutoCommandBufferBuilder::secondary_graphics(
self.gfx_queue.device().clone(),
self.gfx_queue.family(),
CommandBufferUsage::MultipleSubmit,
self.pipeline.subpass().clone(),
)
.unwrap();

View File

@ -10,9 +10,9 @@
use cgmath::Vector3;
use vulkano::buffer::BufferUsage;
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::DynamicState;
use vulkano::command_buffer::SecondaryAutoCommandBuffer;
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SecondaryAutoCommandBuffer,
};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::Queue;
use vulkano::image::ImageViewAbstract;
@ -156,6 +156,7 @@ impl DirectionalLightingSystem {
let mut builder = AutoCommandBufferBuilder::secondary_graphics(
self.gfx_queue.device().clone(),
self.gfx_queue.family(),
CommandBufferUsage::MultipleSubmit,
self.pipeline.subpass().clone(),
)
.unwrap();

View File

@ -11,9 +11,9 @@ use cgmath::Matrix4;
use cgmath::Vector3;
use vulkano::buffer::BufferUsage;
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::DynamicState;
use vulkano::command_buffer::SecondaryAutoCommandBuffer;
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SecondaryAutoCommandBuffer,
};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::Queue;
use vulkano::image::ImageViewAbstract;
@ -171,6 +171,7 @@ impl PointLightingSystem {
let mut builder = AutoCommandBufferBuilder::secondary_graphics(
self.gfx_queue.device().clone(),
self.gfx_queue.family(),
CommandBufferUsage::MultipleSubmit,
self.pipeline.subpass().clone(),
)
.unwrap();

View File

@ -14,10 +14,10 @@ use cgmath::Matrix4;
use cgmath::SquareMatrix;
use cgmath::Vector3;
use std::sync::Arc;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::PrimaryAutoCommandBuffer;
use vulkano::command_buffer::SecondaryCommandBuffer;
use vulkano::command_buffer::SubpassContents;
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, SecondaryCommandBuffer,
SubpassContents,
};
use vulkano::device::Queue;
use vulkano::format::Format;
use vulkano::image::view::ImageView;
@ -299,9 +299,10 @@ impl FrameSystem {
);
// Start the command buffer builder that will be filled throughout the frame handling.
let mut command_buffer_builder = AutoCommandBufferBuilder::primary_one_time_submit(
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
self.gfx_queue.device().clone(),
self.gfx_queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
command_buffer_builder

View File

@ -9,9 +9,9 @@
use vulkano::buffer::BufferUsage;
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::DynamicState;
use vulkano::command_buffer::SecondaryAutoCommandBuffer;
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SecondaryAutoCommandBuffer,
};
use vulkano::device::Queue;
use vulkano::pipeline::viewport::Viewport;
use vulkano::pipeline::GraphicsPipeline;
@ -83,6 +83,7 @@ impl TriangleDrawSystem {
let mut builder = AutoCommandBufferBuilder::secondary_graphics(
self.gfx_queue.device().clone(),
self.gfx_queue.family(),
CommandBufferUsage::MultipleSubmit,
self.pipeline.subpass().clone(),
)
.unwrap();

View File

@ -17,7 +17,7 @@
use std::mem;
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescTweaks};
use vulkano::descriptor::PipelineLayoutAbstract;
@ -165,8 +165,12 @@ fn main() {
);
// Build the command buffer, using different offsets for each call.
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.dispatch(
[12, 1, 1],

View File

@ -19,7 +19,7 @@ use std::io::BufWriter;
use std::path::Path;
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano::device::{Device, DeviceExtensions};
@ -194,8 +194,12 @@ fn main() {
)
.unwrap();
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.dispatch(
[

View File

@ -8,7 +8,9 @@
// according to those terms.
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::format::Format;
@ -28,16 +30,14 @@ use vulkano::swapchain::{
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use png;
use std::io::Cursor;
use std::sync::Arc;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use png;
use std::io::Cursor;
use std::sync::Arc;
fn main() {
// The start of this example is exactly the same as `triangle`. You should read the
// `triangle` example if you haven't done so yet.
@ -274,9 +274,12 @@ fn main() {
}
let clear_values = vec![[0.0, 0.0, 1.0, 1.0].into()];
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.begin_render_pass(
framebuffers[image_num].clone(),

View File

@ -9,8 +9,9 @@
// This example demonstrates how to initialize immutable buffers.
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, ImmutableBuffer};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano::device::{Device, DeviceExtensions};
@ -19,8 +20,6 @@ use vulkano::pipeline::ComputePipeline;
use vulkano::sync;
use vulkano::sync::GpuFuture;
use std::sync::Arc;
fn main() {
// The most part of this example is exactly the same as `basic-compute-shader`. You should read the
// `basic-compute-shader` example if you haven't done so yet.
@ -91,9 +90,12 @@ void main() {
};
// Build command buffer which initialize our buffer.
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
// Initializing a immutable buffer is done by coping data to
// ImmutableBufferInitialization which is returned by a function we use to create buffer.
@ -130,8 +132,12 @@ void main() {
.unwrap(),
);
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), (), vec![])

View File

@ -30,9 +30,12 @@ extern crate vulkano_shaders;
extern crate vulkano_win;
extern crate winit;
use std::iter;
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuBufferPool};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, DrawIndirectCommand, DynamicState, SubpassContents,
AutoCommandBufferBuilder, CommandBufferUsage, DrawIndirectCommand, DynamicState,
SubpassContents,
};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::PipelineLayoutAbstract;
@ -50,15 +53,11 @@ use vulkano::swapchain::{
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use std::iter;
use std::sync::Arc;
// # Vertex Types
// `Vertex` is the vertex type that will be output from the compute shader and be input to the vertex shader.
#[derive(Default, Debug, Clone)]
@ -336,9 +335,10 @@ fn main() {
.unwrap(),
);
let mut builder = AutoCommandBufferBuilder::primary_one_time_submit(
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();

View File

@ -19,7 +19,9 @@ extern crate vulkano_win;
extern crate winit;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageUsage, SwapchainImage};
@ -35,7 +37,6 @@ use vulkano::swapchain::{
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -313,9 +314,10 @@ fn main() {
let clear_values = vec![[0.0, 0.0, 1.0, 1.0].into()];
let mut builder = AutoCommandBufferBuilder::primary_one_time_submit(
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder

View File

@ -71,7 +71,8 @@ use std::path::Path;
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, DynamicState, PrimaryCommandBuffer, SubpassContents,
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, PrimaryCommandBuffer,
SubpassContents,
};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::format::ClearValue;
@ -269,8 +270,12 @@ fn main() {
)
.unwrap();
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.begin_render_pass(
framebuffer.clone(),

View File

@ -16,8 +16,12 @@
// and that you want to learn Vulkan. This means that for example it won't go into details about
// what a vertex or a shader is.
use std::collections::HashMap;
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageUsage, SwapchainImage};
@ -33,7 +37,6 @@ use vulkano::swapchain::{
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::event::ElementState;
use winit::event::KeyboardInput;
@ -41,9 +44,6 @@ use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use std::collections::HashMap;
use std::sync::Arc;
// A struct to contain resources related to a window
struct WindowSurface {
surface: Arc<Surface<Window>>,
@ -367,9 +367,12 @@ fn main() {
let clear_values = vec![[0.0, 0.0, 1.0, 1.0].into()];
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.begin_render_pass(

View File

@ -13,7 +13,9 @@
use std::sync::Arc;
use vulkano::buffer::{BufferAccess, BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::device::{Device, DeviceExtensions, DeviceOwned};
use vulkano::format::Format;
use vulkano::image::{view::ImageView, AttachmentImage, ImageUsage, SwapchainImage};
@ -317,9 +319,12 @@ fn main() {
let clear_values = vec![[0.0, 0.0, 1.0, 1.0].into(), 1.0.into()];
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
// Beginning or resetting a query is unsafe for now.
unsafe {

View File

@ -9,8 +9,9 @@
// TODO: Give a paragraph about what push constants are and what problems they solve
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano::device::{Device, DeviceExtensions};
@ -19,8 +20,6 @@ use vulkano::pipeline::ComputePipeline;
use vulkano::sync;
use vulkano::sync::GpuFuture;
use std::sync::Arc;
fn main() {
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
@ -101,8 +100,12 @@ fn main() {
// For a graphics pipeline, push constants are passed to the `draw` and `draw_indexed` methods.
// Note that there is no type safety for the push constants argument.
// So be careful to only pass an instance of the struct generated by the `vulkano_shaders::shaders!` macro.
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.dispatch(
[1024, 1, 1],

View File

@ -19,10 +19,17 @@
// $ glslangValidator frag.glsl -V -S frag -o frag.spv
// Vulkano uses glslangValidator to build your shaders internally.
use std::borrow::Cow;
use std::ffi::CStr;
use std::fs::File;
use std::io::Read;
use std::sync::Arc;
use vulkano as vk;
use vulkano::buffer::cpu_access::CpuAccessibleBuffer;
use vulkano::buffer::BufferUsage;
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::descriptor::descriptor::DescriptorDesc;
use vulkano::descriptor::descriptor::ShaderStages;
use vulkano::descriptor::pipeline_layout::PipelineLayoutDesc;
@ -47,18 +54,11 @@ use vulkano::swapchain::{
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use std::borrow::Cow;
use std::ffi::CStr;
use std::fs::File;
use std::io::Read;
use std::sync::Arc;
#[derive(Default, Copy, Clone)]
pub struct Vertex {
pub position: [f32; 2],
@ -517,8 +517,12 @@ fn main() {
}
let clear_values = vec![[0.0, 0.0, 0.0, 1.0].into()];
let mut builder =
AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
builder
.begin_render_pass(
framebuffers[image_num].clone(),

View File

@ -11,8 +11,9 @@
// shader source code. The boilerplate is taken from the "basic-compute-shader.rs" example, where
// most of the boilerplate is explained.
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano::device::{Device, DeviceExtensions};
@ -21,8 +22,6 @@ use vulkano::pipeline::ComputePipeline;
use vulkano::sync;
use vulkano::sync::GpuFuture;
use std::sync::Arc;
fn main() {
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
@ -91,8 +90,12 @@ fn main() {
.build()
.unwrap(),
);
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), (), vec![])
.unwrap();

View File

@ -9,8 +9,9 @@
// TODO: Give a paragraph about what specialization are and what problems they solve
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano::device::{Device, DeviceExtensions};
@ -19,8 +20,6 @@ use vulkano::pipeline::ComputePipeline;
use vulkano::sync;
use vulkano::sync::GpuFuture;
use std::sync::Arc;
fn main() {
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
@ -99,8 +98,12 @@ fn main() {
.unwrap(),
);
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), (), vec![])
.unwrap();

View File

@ -7,9 +7,16 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use cgmath::{Matrix3, Matrix4, Point3, Rad, Vector3};
use examples::{Normal, Vertex, INDICES, NORMALS, VERTICES};
use std::iter;
use std::sync::Arc;
use std::time::Instant;
use vulkano::buffer::cpu_pool::CpuBufferPool;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::format::Format;
@ -29,20 +36,11 @@ use vulkano::swapchain::{
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use cgmath::{Matrix3, Matrix4, Point3, Rad, Vector3};
use examples::{Normal, Vertex, INDICES, NORMALS, VERTICES};
use std::iter;
use std::sync::Arc;
use std::time::Instant;
fn main() {
// The start of this example is exactly the same as `triangle`. You should read the
// `triangle` example if you haven't done so yet.
@ -248,9 +246,10 @@ fn main() {
recreate_swapchain = true;
}
let mut builder = AutoCommandBufferBuilder::primary_one_time_submit(
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder

View File

@ -18,8 +18,11 @@
// * tessellation control shader and a tessellation evaluation shader
// * tessellation_shaders(..), patch_list(3) and polygon_mode_line() are called on the pipeline builder
use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageUsage, SwapchainImage};
@ -34,14 +37,11 @@ use vulkano::swapchain::{
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use std::sync::Arc;
mod vs {
vulkano_shaders::shader! {
ty: "vertex",
@ -346,9 +346,12 @@ fn main() {
recreate_swapchain = true;
}
let mut builder =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
builder
.begin_render_pass(
framebuffers[image_num].clone(),

View File

@ -17,7 +17,9 @@
// what a vertex or a shader is.
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, SubpassContents};
use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, DynamicState, SubpassContents,
};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageUsage, SwapchainImage};
@ -448,9 +450,10 @@ fn main() {
//
// 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.
let mut builder = AutoCommandBufferBuilder::primary_one_time_submit(
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();

View File

@ -7,19 +7,6 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use std::cmp;
use std::hash::Hash;
use std::hash::Hasher;
use std::iter;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::MutexGuard;
use crate::buffer::sys::BufferCreationError;
use crate::buffer::sys::SparseLevel;
use crate::buffer::sys::UnsafeBuffer;
@ -42,6 +29,18 @@ use crate::memory::DedicatedAlloc;
use crate::memory::DeviceMemoryAllocError;
use crate::sync::AccessError;
use crate::sync::Sharing;
use std::cmp;
use std::hash::Hash;
use std::hash::Hasher;
use std::iter;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::MutexGuard;
use crate::OomError;
@ -73,6 +72,7 @@ use crate::OomError;
/// ```
/// use vulkano::buffer::CpuBufferPool;
/// use vulkano::command_buffer::AutoCommandBufferBuilder;
/// use vulkano::command_buffer::CommandBufferUsage;
/// use vulkano::command_buffer::PrimaryCommandBuffer;
/// use vulkano::sync::GpuFuture;
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
@ -87,7 +87,7 @@ use crate::OomError;
/// let sub_buffer = buffer.next(data).unwrap();
///
/// // You can then use `sub_buffer` as if it was an entirely separate buffer.
/// AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
/// AutoCommandBufferBuilder::primary(device.clone(), queue.family(), CommandBufferUsage::OneTimeSubmit)
/// .unwrap()
/// // For the sake of the example we just call `update_buffer` on the buffer, even though
/// // it is pointless to do that.

View File

@ -28,6 +28,7 @@ use crate::buffer::BufferUsage;
use crate::buffer::CpuAccessibleBuffer;
use crate::command_buffer::AutoCommandBufferBuilder;
use crate::command_buffer::CommandBufferExecFuture;
use crate::command_buffer::CommandBufferUsage;
use crate::command_buffer::PrimaryAutoCommandBuffer;
use crate::command_buffer::PrimaryCommandBuffer;
use crate::device::Device;
@ -136,7 +137,11 @@ impl<T: ?Sized> ImmutableBuffer<T> {
source.device().active_queue_families(),
)?;
let mut cbb = AutoCommandBufferBuilder::new(source.device().clone(), queue.family())?;
let mut cbb = AutoCommandBufferBuilder::primary(
source.device().clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)?;
cbb.copy_buffer(source, init).unwrap(); // TODO: return error?
let cb = cbb.build().unwrap(); // TODO: return OomError
@ -534,6 +539,7 @@ mod tests {
use crate::buffer::immutable::ImmutableBuffer;
use crate::buffer::BufferUsage;
use crate::command_buffer::AutoCommandBufferBuilder;
use crate::command_buffer::CommandBufferUsage;
use crate::command_buffer::PrimaryCommandBuffer;
use crate::sync::GpuFuture;
@ -547,7 +553,12 @@ mod tests {
let destination =
CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), false, 0).unwrap();
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
cbb.copy_buffer(buffer, destination.clone()).unwrap();
let _ = cbb
.build()
@ -580,7 +591,12 @@ mod tests {
)
.unwrap();
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
cbb.copy_buffer(buffer, destination.clone()).unwrap();
let _ = cbb
.build()
@ -605,7 +621,12 @@ mod tests {
assert_should_panic!({
// TODO: check Result error instead of panicking
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
cbb.fill_buffer(buffer, 50).unwrap();
let _ = cbb
.build()
@ -630,7 +651,12 @@ mod tests {
assert_should_panic!({
// TODO: check Result error instead of panicking
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
cbb.copy_buffer(source, buffer).unwrap();
let _ = cbb
.build()
@ -653,7 +679,12 @@ mod tests {
let source =
CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), false, 0).unwrap();
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
cbb.copy_buffer(source.clone(), init)
.unwrap()
.copy_buffer(buffer, source.clone())
@ -679,11 +710,21 @@ mod tests {
let source =
CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), false, 0).unwrap();
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
cbb.copy_buffer(source.clone(), init).unwrap();
let cb1 = cbb.build().unwrap();
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
cbb.copy_buffer(buffer, source.clone()).unwrap();
let cb2 = cbb.build().unwrap();

View File

@ -16,7 +16,6 @@ use crate::command_buffer::pool::CommandPoolBuilderAlloc;
use crate::command_buffer::synced::SyncCommandBuffer;
use crate::command_buffer::synced::SyncCommandBufferBuilder;
use crate::command_buffer::synced::SyncCommandBufferBuilderError;
use crate::command_buffer::sys::Flags;
use crate::command_buffer::sys::UnsafeCommandBuffer;
use crate::command_buffer::sys::UnsafeCommandBufferBuilderBufferImageCopy;
use crate::command_buffer::sys::UnsafeCommandBufferBuilderColorImageClear;
@ -27,6 +26,7 @@ use crate::command_buffer::CommandBufferExecError;
use crate::command_buffer::CommandBufferInheritance;
use crate::command_buffer::CommandBufferInheritanceRenderPass;
use crate::command_buffer::CommandBufferLevel;
use crate::command_buffer::CommandBufferUsage;
use crate::command_buffer::DispatchIndirectCommand;
use crate::command_buffer::DrawIndexedIndirectCommand;
use crate::command_buffer::DrawIndirectCommand;
@ -103,8 +103,8 @@ pub struct AutoCommandBufferBuilder<L, P = StandardCommandPoolBuilder> {
// The inheritance for secondary command buffers.
inheritance: Option<CommandBufferInheritance<Box<dyn FramebufferAbstract + Send + Sync>>>,
// Flags passed when creating the command buffer.
flags: Flags,
// Usage flags passed when creating the command buffer.
usage: CommandBufferUsage,
// If we're inside a render pass, contains the render pass state.
render_pass_state: Option<RenderPassState>,
@ -132,132 +132,38 @@ struct QueryState {
}
impl AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder> {
#[inline]
pub fn new(
device: Arc<Device>,
queue_family: QueueFamily,
) -> Result<
AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
AutoCommandBufferBuilder::with_flags(
device,
queue_family,
CommandBufferLevel::primary(),
Flags::None,
)
}
/// Starts building a primary command buffer.
///
/// The final command buffer can only be executed once at a time. In other words, it is as if
/// executing the command buffer modifies it.
#[inline]
pub fn primary(
device: Arc<Device>,
queue_family: QueueFamily,
usage: CommandBufferUsage,
) -> Result<
AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
AutoCommandBufferBuilder::with_flags(
AutoCommandBufferBuilder::with_level(
device,
queue_family,
usage,
CommandBufferLevel::primary(),
Flags::None,
)
}
/// Starts building a primary command buffer.
///
/// Contrary to `primary`, the final command buffer can only be submitted once before being
/// destroyed. This makes it possible for the implementation to perform additional
/// optimizations.
#[inline]
pub fn primary_one_time_submit(
device: Arc<Device>,
queue_family: QueueFamily,
) -> Result<
AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
AutoCommandBufferBuilder::with_flags(
device,
queue_family,
CommandBufferLevel::primary(),
Flags::OneTimeSubmit,
)
}
/// Starts building a primary command buffer.
///
/// Contrary to `primary`, the final command buffer can be executed multiple times in parallel
/// in multiple different queues.
#[inline]
pub fn primary_simultaneous_use(
device: Arc<Device>,
queue_family: QueueFamily,
) -> Result<
AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
AutoCommandBufferBuilder::with_flags(
device,
queue_family,
CommandBufferLevel::primary(),
Flags::SimultaneousUse,
)
}
}
impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder> {
/// Starts building a secondary compute command buffer.
///
/// The final command buffer can only be executed once at a time. In other words, it is as if
/// executing the command buffer modifies it.
#[inline]
pub fn secondary_compute(
device: Arc<Device>,
queue_family: QueueFamily,
usage: CommandBufferUsage,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
let level = CommandBufferLevel::secondary(None, QueryPipelineStatisticFlags::none());
AutoCommandBufferBuilder::with_flags(device, queue_family, level, Flags::None)
}
/// Starts building a secondary compute command buffer.
///
/// Contrary to `secondary_compute`, the final command buffer can only be submitted once before
/// being destroyed. This makes it possible for the implementation to perform additional
/// optimizations.
#[inline]
pub fn secondary_compute_one_time_submit(
device: Arc<Device>,
queue_family: QueueFamily,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
let level = CommandBufferLevel::secondary(None, QueryPipelineStatisticFlags::none());
AutoCommandBufferBuilder::with_flags(device, queue_family, level, Flags::OneTimeSubmit)
}
/// Starts building a secondary compute command buffer.
///
/// Contrary to `secondary_compute`, the final command buffer can be executed multiple times in
/// parallel in multiple different queues.
#[inline]
pub fn secondary_compute_simultaneous_use(
device: Arc<Device>,
queue_family: QueueFamily,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
let level = CommandBufferLevel::secondary(None, QueryPipelineStatisticFlags::none());
AutoCommandBufferBuilder::with_flags(device, queue_family, level, Flags::SimultaneousUse)
AutoCommandBufferBuilder::with_level(device, queue_family, usage, level)
}
/// Same as `secondary_compute`, but allows specifying how queries are being inherited.
@ -265,6 +171,7 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
pub fn secondary_compute_inherit_queries(
device: Arc<Device>,
queue_family: QueueFamily,
usage: CommandBufferUsage,
occlusion_query: Option<QueryControlFlags>,
query_statistics_flags: QueryPipelineStatisticFlags,
) -> Result<
@ -282,82 +189,20 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
}
let level = CommandBufferLevel::secondary(occlusion_query, query_statistics_flags);
Ok(AutoCommandBufferBuilder::with_flags(
Ok(AutoCommandBufferBuilder::with_level(
device,
queue_family,
usage,
level,
Flags::None,
)?)
}
/// Same as `secondary_compute_one_time_submit`, but allows specifying how queries are being inherited.
#[inline]
pub fn secondary_compute_one_time_submit_inherit_queries(
device: Arc<Device>,
queue_family: QueueFamily,
occlusion_query: Option<QueryControlFlags>,
query_statistics_flags: QueryPipelineStatisticFlags,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
BeginError,
> {
if occlusion_query.is_some() && !device.enabled_features().inherited_queries {
return Err(BeginError::InheritedQueriesFeatureNotEnabled);
}
if query_statistics_flags.count() > 0
&& !device.enabled_features().pipeline_statistics_query
{
return Err(BeginError::PipelineStatisticsQueryFeatureNotEnabled);
}
let level = CommandBufferLevel::secondary(occlusion_query, query_statistics_flags);
Ok(AutoCommandBufferBuilder::with_flags(
device,
queue_family,
level,
Flags::OneTimeSubmit,
)?)
}
/// Same as `secondary_compute_simultaneous_use`, but allows specifying how queries are being inherited.
#[inline]
pub fn secondary_compute_simultaneous_use_inherit_queries(
device: Arc<Device>,
queue_family: QueueFamily,
occlusion_query: Option<QueryControlFlags>,
query_statistics_flags: QueryPipelineStatisticFlags,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
BeginError,
> {
if occlusion_query.is_some() && !device.enabled_features().inherited_queries {
return Err(BeginError::InheritedQueriesFeatureNotEnabled);
}
if query_statistics_flags.count() > 0
&& !device.enabled_features().pipeline_statistics_query
{
return Err(BeginError::PipelineStatisticsQueryFeatureNotEnabled);
}
let level = CommandBufferLevel::secondary(occlusion_query, query_statistics_flags);
Ok(AutoCommandBufferBuilder::with_flags(
device,
queue_family,
level,
Flags::SimultaneousUse,
)?)
}
/// Starts building a secondary graphics command buffer.
///
/// The final command buffer can only be executed once at a time. In other words, it is as if
/// executing the command buffer modifies it.
#[inline]
pub fn secondary_graphics(
device: Arc<Device>,
queue_family: QueueFamily,
usage: CommandBufferUsage,
subpass: Subpass,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
@ -372,58 +217,7 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
query_statistics_flags: QueryPipelineStatisticFlags::none(),
});
AutoCommandBufferBuilder::with_flags(device, queue_family, level, Flags::None)
}
/// Starts building a secondary graphics command buffer.
///
/// Contrary to `secondary_graphics`, the final command buffer can only be submitted once
/// before being destroyed. This makes it possible for the implementation to perform additional
/// optimizations.
#[inline]
pub fn secondary_graphics_one_time_submit<R>(
device: Arc<Device>,
queue_family: QueueFamily,
subpass: Subpass,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
let level = CommandBufferLevel::Secondary(CommandBufferInheritance {
render_pass: Some(CommandBufferInheritanceRenderPass {
subpass,
framebuffer: None::<Arc<Framebuffer<()>>>,
}),
occlusion_query: None,
query_statistics_flags: QueryPipelineStatisticFlags::none(),
});
AutoCommandBufferBuilder::with_flags(device, queue_family, level, Flags::OneTimeSubmit)
}
/// Starts building a secondary graphics command buffer.
///
/// Contrary to `secondary_graphics`, the final command buffer can be executed multiple times
/// in parallel in multiple different queues.
#[inline]
pub fn secondary_graphics_simultaneous_use<R>(
device: Arc<Device>,
queue_family: QueueFamily,
subpass: Subpass,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
OomError,
> {
let level = CommandBufferLevel::Secondary(CommandBufferInheritance {
render_pass: Some(CommandBufferInheritanceRenderPass {
subpass,
framebuffer: None::<Arc<Framebuffer<()>>>,
}),
occlusion_query: None,
query_statistics_flags: QueryPipelineStatisticFlags::none(),
});
AutoCommandBufferBuilder::with_flags(device, queue_family, level, Flags::SimultaneousUse)
AutoCommandBufferBuilder::with_level(device, queue_family, usage, level)
}
/// Same as `secondary_graphics`, but allows specifying how queries are being inherited.
@ -431,6 +225,7 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
pub fn secondary_graphics_inherit_queries(
device: Arc<Device>,
queue_family: QueueFamily,
usage: CommandBufferUsage,
subpass: Subpass,
occlusion_query: Option<QueryControlFlags>,
query_statistics_flags: QueryPipelineStatisticFlags,
@ -457,100 +252,22 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
query_statistics_flags,
});
Ok(AutoCommandBufferBuilder::with_flags(
Ok(AutoCommandBufferBuilder::with_level(
device,
queue_family,
usage,
level,
Flags::None,
)?)
}
/// Same as `secondary_graphics_one_time_submit`, but allows specifying how queries are being inherited.
#[inline]
pub fn secondary_graphics_one_time_submit_inherit_queries(
device: Arc<Device>,
queue_family: QueueFamily,
subpass: Subpass,
occlusion_query: Option<QueryControlFlags>,
query_statistics_flags: QueryPipelineStatisticFlags,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
BeginError,
> {
if occlusion_query.is_some() && !device.enabled_features().inherited_queries {
return Err(BeginError::InheritedQueriesFeatureNotEnabled);
}
if query_statistics_flags.count() > 0
&& !device.enabled_features().pipeline_statistics_query
{
return Err(BeginError::PipelineStatisticsQueryFeatureNotEnabled);
}
let level = CommandBufferLevel::Secondary(CommandBufferInheritance {
render_pass: Some(CommandBufferInheritanceRenderPass {
subpass,
framebuffer: None::<Arc<Framebuffer<()>>>,
}),
occlusion_query,
query_statistics_flags,
});
Ok(AutoCommandBufferBuilder::with_flags(
device,
queue_family,
level,
Flags::OneTimeSubmit,
)?)
}
/// Same as `secondary_graphics_simultaneous_use`, but allows specifying how queries are being inherited.
#[inline]
pub fn secondary_graphics_simultaneous_use_inherit_queries(
device: Arc<Device>,
queue_family: QueueFamily,
subpass: Subpass,
occlusion_query: Option<QueryControlFlags>,
query_statistics_flags: QueryPipelineStatisticFlags,
) -> Result<
AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBuilder>,
BeginError,
> {
if occlusion_query.is_some() && !device.enabled_features().inherited_queries {
return Err(BeginError::InheritedQueriesFeatureNotEnabled);
}
if query_statistics_flags.count() > 0
&& !device.enabled_features().pipeline_statistics_query
{
return Err(BeginError::PipelineStatisticsQueryFeatureNotEnabled);
}
let level = CommandBufferLevel::Secondary(CommandBufferInheritance {
render_pass: Some(CommandBufferInheritanceRenderPass {
subpass,
framebuffer: None::<Arc<Framebuffer<()>>>,
}),
occlusion_query,
query_statistics_flags,
});
Ok(AutoCommandBufferBuilder::with_flags(
device,
queue_family,
level,
Flags::SimultaneousUse,
)?)
}
}
impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
// Actual constructor. Private.
fn with_flags<F>(
fn with_level<F>(
device: Arc<Device>,
queue_family: QueueFamily,
usage: CommandBufferUsage,
level: CommandBufferLevel<F>,
flags: Flags,
) -> Result<AutoCommandBufferBuilder<L, StandardCommandPoolBuilder>, OomError>
where
F: FramebufferAbstract + Clone + Send + Sync + 'static,
@ -597,7 +314,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
.alloc(!matches!(level, CommandBufferLevel::Primary), 1)?
.next()
.expect("Requested one command buffer from the command pool, but got zero.");
let inner = SyncCommandBufferBuilder::new(pool_builder_alloc.inner(), level, flags)?;
let inner = SyncCommandBufferBuilder::new(pool_builder_alloc.inner(), level, usage)?;
Ok(AutoCommandBufferBuilder {
inner,
@ -607,7 +324,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
render_pass_state,
query_state: FnvHashMap::default(),
inheritance,
flags,
usage,
_data: PhantomData,
})
}
@ -677,12 +394,12 @@ where
return Err(AutoCommandBufferBuilderContextError::QueryIsActive.into());
}
let submit_state = match self.flags {
Flags::None => SubmitState::ExclusiveUse {
let submit_state = match self.usage {
CommandBufferUsage::MultipleSubmit => SubmitState::ExclusiveUse {
in_use: AtomicBool::new(false),
},
Flags::SimultaneousUse => SubmitState::Concurrent,
Flags::OneTimeSubmit => SubmitState::OneTime {
CommandBufferUsage::SimultaneousUse => SubmitState::Concurrent,
CommandBufferUsage::OneTimeSubmit => SubmitState::OneTime {
already_submitted: AtomicBool::new(false),
},
};
@ -706,12 +423,12 @@ where
return Err(AutoCommandBufferBuilderContextError::QueryIsActive.into());
}
let submit_state = match self.flags {
Flags::None => SubmitState::ExclusiveUse {
let submit_state = match self.usage {
CommandBufferUsage::MultipleSubmit => SubmitState::ExclusiveUse {
in_use: AtomicBool::new(false),
},
Flags::SimultaneousUse => SubmitState::Concurrent,
Flags::OneTimeSubmit => SubmitState::OneTime {
CommandBufferUsage::SimultaneousUse => SubmitState::Concurrent,
CommandBufferUsage::OneTimeSubmit => SubmitState::OneTime {
already_submitted: AtomicBool::new(false),
},
};
@ -2127,7 +1844,7 @@ where
C: SecondaryCommandBuffer + Send + Sync + 'static,
{
self.check_command_buffer(&command_buffer)?;
let secondary_flags = command_buffer.inner().flags();
let secondary_usage = command_buffer.inner().usage();
unsafe {
let mut builder = self.inner.execute_commands();
@ -2139,7 +1856,7 @@ where
self.state_cacher.invalidate();
// If the secondary is non-concurrent or one-time use, that restricts the primary as well.
self.flags = std::cmp::min(self.flags, secondary_flags);
self.usage = std::cmp::min(self.usage, secondary_usage);
Ok(self)
}
@ -2161,11 +1878,11 @@ where
self.check_command_buffer(command_buffer)?;
}
let mut secondary_flags = Flags::SimultaneousUse; // Most permissive flags
let mut secondary_usage = CommandBufferUsage::SimultaneousUse; // Most permissive usage
unsafe {
let mut builder = self.inner.execute_commands();
for command_buffer in command_buffers {
secondary_flags = std::cmp::min(secondary_flags, command_buffer.inner().flags());
secondary_usage = std::cmp::min(secondary_usage, command_buffer.inner().usage());
builder.add(command_buffer);
}
builder.submit()?;
@ -2175,7 +1892,7 @@ where
self.state_cacher.invalidate();
// If the secondary is non-concurrent or one-time use, that restricts the primary as well.
self.flags = std::cmp::min(self.flags, secondary_flags);
self.usage = std::cmp::min(self.usage, secondary_usage);
Ok(self)
}
@ -3017,6 +2734,7 @@ mod tests {
use crate::command_buffer::synced::SyncCommandBufferBuilderError;
use crate::command_buffer::AutoCommandBufferBuilder;
use crate::command_buffer::CommandBufferExecError;
use crate::command_buffer::CommandBufferUsage;
use crate::command_buffer::ExecuteCommandsError;
use crate::command_buffer::PrimaryCommandBuffer;
use crate::device::Device;
@ -3066,9 +2784,12 @@ mod tests {
)
.unwrap();
let mut cbb =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
cbb.copy_buffer_dimensions(source.clone(), 0, destination.clone(), 1, 2)
.unwrap();
@ -3092,14 +2813,21 @@ mod tests {
let (device, queue) = gfx_dev_and_queue!();
// Make a secondary CB that doesn't support simultaneous use.
let builder =
AutoCommandBufferBuilder::secondary_compute(device.clone(), queue.family()).unwrap();
let builder = AutoCommandBufferBuilder::secondary_compute(
device.clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
let secondary = Arc::new(builder.build().unwrap());
{
let mut builder =
AutoCommandBufferBuilder::primary_simultaneous_use(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::SimultaneousUse,
)
.unwrap();
// Add the secondary a first time
builder.execute_commands(secondary.clone()).unwrap();
@ -3117,15 +2845,21 @@ mod tests {
}
{
let mut builder =
AutoCommandBufferBuilder::primary_simultaneous_use(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::SimultaneousUse,
)
.unwrap();
builder.execute_commands(secondary.clone()).unwrap();
let cb1 = builder.build().unwrap();
let mut builder =
AutoCommandBufferBuilder::primary_simultaneous_use(device.clone(), queue.family())
.unwrap();
let mut builder = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::SimultaneousUse,
)
.unwrap();
// Recording the same non-concurrent secondary command buffer into multiple
// primaries is an error.

View File

@ -37,25 +37,28 @@
//! # The `AutoCommandBufferBuilder`
//!
//! The most basic (and recommended) way to create a command buffer is to create a
//! [`AutoCommandBufferBuilder`](struct.AutoCommandBufferBuilder.html). Then use the
//! [`CommandBufferBuilder` trait](trait.CommandBufferBuilder.html) to add commands to it.
//! When you are done adding commands, use
//! [the `CommandBufferBuild` trait](trait.CommandBufferBuild.html) to obtain a
//! `AutoCommandBuffer`.
//! [`AutoCommandBufferBuilder`](struct.AutoCommandBufferBuilder.html), then record commands to it.
//! When you are done adding commands, build it to obtain either a `PrimaryAutoCommandBuffer` or
//! `SecondAutoCommandBuffer`.
//!
//! Once built, use [the `CommandBuffer` trait](trait.CommandBuffer.html) to submit the command
//! buffer. Submitting a command buffer returns an object that implements the `GpuFuture` trait and
//! that represents the moment when the execution will end on the GPU.
//! Once built, use [the `PrimaryCommandBuffer` trait](trait.PrimaryCommandBuffer.html) to submit the
//! command buffer. Submitting a command buffer returns an object that implements the `GpuFuture` trait
//! and that represents the moment when the execution will end on the GPU.
//!
//! ```
//! use vulkano::command_buffer::AutoCommandBufferBuilder;
//! use vulkano::command_buffer::CommandBufferUsage;
//! use vulkano::command_buffer::PrimaryCommandBuffer;
//!
//! # let device: std::sync::Arc<vulkano::device::Device> = return;
//! # let queue: std::sync::Arc<vulkano::device::Queue> = return;
//! let cb = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap()
//! // TODO: add an actual command to this example
//! .build().unwrap();
//! let cb = AutoCommandBufferBuilder::primary(
//! device.clone(),
//! queue.family(),
//! CommandBufferUsage::MultipleSubmit
//! ).unwrap()
//! // TODO: add an actual command to this example
//! .build().unwrap();
//!
//! let _future = cb.execute(queue.clone());
//! ```
@ -270,3 +273,35 @@ impl CommandBufferLevel<Framebuffer<()>> {
})
}
}
/// Usage flags to pass when creating a command buffer.
///
/// The safest option is `SimultaneousUse`, but it may be slower than the other two.
// NOTE: The ordering is important: the variants are listed from least to most permissive!
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum CommandBufferUsage {
/// The command buffer can only be submitted once before being destroyed. Any further submit is
/// forbidden. This makes it possible for the implementation to perform additional
/// optimizations.
OneTimeSubmit,
/// The command buffer can be used multiple times, but must not execute or record more than once
/// simultaneously. In other words, it is as if executing the command buffer borrows it mutably.
MultipleSubmit,
/// The command buffer can be executed multiple times in parallel on different queues.
/// If it's a secondary command buffer, it can be recorded to multiple primary command buffers
/// at once.
SimultaneousUse,
}
impl From<CommandBufferUsage> for vk::CommandBufferUsageFlags {
#[inline]
fn from(val: CommandBufferUsage) -> Self {
match val {
CommandBufferUsage::OneTimeSubmit => vk::COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
CommandBufferUsage::MultipleSubmit => 0,
CommandBufferUsage::SimultaneousUse => vk::COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
}
}
}

View File

@ -9,12 +9,12 @@
use crate::buffer::BufferAccess;
use crate::command_buffer::pool::UnsafeCommandPoolAlloc;
use crate::command_buffer::sys::Flags;
use crate::command_buffer::sys::UnsafeCommandBuffer;
use crate::command_buffer::sys::UnsafeCommandBufferBuilder;
use crate::command_buffer::sys::UnsafeCommandBufferBuilderPipelineBarrier;
use crate::command_buffer::CommandBufferExecError;
use crate::command_buffer::CommandBufferLevel;
use crate::command_buffer::CommandBufferUsage;
use crate::device::Device;
use crate::device::DeviceOwned;
use crate::device::Queue;
@ -426,7 +426,7 @@ impl SyncCommandBufferBuilder {
pub unsafe fn new<F>(
pool_alloc: &UnsafeCommandPoolAlloc,
level: CommandBufferLevel<F>,
flags: Flags,
usage: CommandBufferUsage,
) -> Result<SyncCommandBufferBuilder, OomError>
where
F: FramebufferAbstract,
@ -438,7 +438,7 @@ impl SyncCommandBufferBuilder {
}
};
let cmd = UnsafeCommandBufferBuilder::new(pool_alloc, level, flags)?;
let cmd = UnsafeCommandBufferBuilder::new(pool_alloc, level, usage)?;
Ok(SyncCommandBufferBuilder::from_unsafe_cmd(
cmd,
is_secondary,
@ -1502,9 +1502,9 @@ mod tests {
use crate::buffer::ImmutableBuffer;
use crate::command_buffer::pool::CommandPool;
use crate::command_buffer::pool::CommandPoolBuilderAlloc;
use crate::command_buffer::sys::Flags;
use crate::command_buffer::AutoCommandBufferBuilder;
use crate::command_buffer::CommandBufferLevel;
use crate::command_buffer::CommandBufferUsage;
use crate::device::Device;
use crate::sync::GpuFuture;
use std::sync::Arc;
@ -1520,7 +1520,7 @@ mod tests {
SyncCommandBufferBuilder::new(
&pool_builder_alloc.inner(),
CommandBufferLevel::primary(),
Flags::None,
CommandBufferUsage::MultipleSubmit,
),
Ok(_)
));
@ -1537,7 +1537,7 @@ mod tests {
let mut sync = SyncCommandBufferBuilder::new(
&pool_builder_alloc.inner(),
CommandBufferLevel::primary(),
Flags::None,
CommandBufferUsage::MultipleSubmit,
)
.unwrap();
let buf =
@ -1571,9 +1571,10 @@ mod tests {
// Two secondary command buffers that both write to the buffer
let secondary = (0..2)
.map(|_| {
let mut builder = AutoCommandBufferBuilder::secondary_compute_simultaneous_use(
let mut builder = AutoCommandBufferBuilder::secondary_compute(
device.clone(),
queue.family(),
CommandBufferUsage::SimultaneousUse,
)
.unwrap();
builder.fill_buffer(buf.clone(), 42u32).unwrap();
@ -1588,7 +1589,7 @@ mod tests {
let mut builder = SyncCommandBufferBuilder::new(
allocs[0].inner(),
CommandBufferLevel::primary(),
Flags::SimultaneousUse,
CommandBufferUsage::SimultaneousUse,
)
.unwrap();
@ -1615,7 +1616,7 @@ mod tests {
let mut builder = SyncCommandBufferBuilder::new(
allocs[1].inner(),
CommandBufferLevel::primary(),
Flags::SimultaneousUse,
CommandBufferUsage::SimultaneousUse,
)
.unwrap();

View File

@ -14,6 +14,7 @@ use crate::check_errors;
use crate::command_buffer::pool::UnsafeCommandPoolAlloc;
use crate::command_buffer::CommandBufferInheritance;
use crate::command_buffer::CommandBufferLevel;
use crate::command_buffer::CommandBufferUsage;
use crate::command_buffer::SecondaryCommandBuffer;
use crate::command_buffer::SubpassContents;
use crate::descriptor::descriptor::ShaderStages;
@ -55,23 +56,6 @@ use std::ops::Range;
use std::ptr;
use std::sync::Arc;
/// Flags to pass when creating a command buffer.
///
/// The safest option is `SimultaneousUse`, but it may be slower than the other two.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Flags {
/// The command buffer can only be submitted once. Any further submit is forbidden.
OneTimeSubmit,
/// The command buffer can be used multiple times, but must not execute or record more than once
/// simultaneously.
None,
/// The command buffer can be executed multiple times in parallel. If it's a secondary command
/// buffer, it can be recorded to multiple primary command buffers at once.
SimultaneousUse,
}
/// Command buffer being built.
///
/// You can add commands to an `UnsafeCommandBufferBuilder` by using the `AddCommand` trait.
@ -83,7 +67,7 @@ pub enum Flags {
pub struct UnsafeCommandBufferBuilder {
command_buffer: vk::CommandBuffer,
device: Arc<Device>,
flags: Flags,
usage: CommandBufferUsage,
}
impl fmt::Debug for UnsafeCommandBufferBuilder {
@ -112,7 +96,7 @@ impl UnsafeCommandBufferBuilder {
pub unsafe fn new<F>(
pool_alloc: &UnsafeCommandPoolAlloc,
level: CommandBufferLevel<F>,
flags: Flags,
usage: CommandBufferUsage,
) -> Result<UnsafeCommandBufferBuilder, OomError>
where
F: FramebufferAbstract,
@ -126,12 +110,7 @@ impl UnsafeCommandBufferBuilder {
let vk = device.pointers();
let vk_flags = {
let a = match flags {
Flags::None => 0,
Flags::SimultaneousUse => vk::COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
Flags::OneTimeSubmit => vk::COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
};
let a = vk::CommandBufferUsageFlags::from(usage);
let b = match level {
CommandBufferLevel::Secondary(ref inheritance)
if inheritance.render_pass.is_some() =>
@ -211,7 +190,7 @@ impl UnsafeCommandBufferBuilder {
Ok(UnsafeCommandBufferBuilder {
command_buffer: pool_alloc.internal_object(),
device: device.clone(),
flags,
usage,
})
}
@ -225,7 +204,7 @@ impl UnsafeCommandBufferBuilder {
Ok(UnsafeCommandBuffer {
command_buffer: self.command_buffer,
device: self.device.clone(),
flags: self.flags,
usage: self.usage,
})
}
}
@ -1953,13 +1932,13 @@ impl UnsafeCommandBufferBuilderPipelineBarrier {
pub struct UnsafeCommandBuffer {
command_buffer: vk::CommandBuffer,
device: Arc<Device>,
flags: Flags,
usage: CommandBufferUsage,
}
impl UnsafeCommandBuffer {
#[inline]
pub fn flags(&self) -> Flags {
self.flags
pub fn usage(&self) -> CommandBufferUsage {
self.usage
}
}

View File

@ -13,6 +13,7 @@ use crate::buffer::CpuAccessibleBuffer;
use crate::buffer::TypedBufferAccess;
use crate::command_buffer::AutoCommandBufferBuilder;
use crate::command_buffer::CommandBufferExecFuture;
use crate::command_buffer::CommandBufferUsage;
use crate::command_buffer::PrimaryAutoCommandBuffer;
use crate::command_buffer::PrimaryCommandBuffer;
use crate::device::Device;
@ -388,7 +389,11 @@ impl ImmutableImage {
ImageLayout::ShaderReadOnlyOptimal,
);
let mut cbb = AutoCommandBufferBuilder::new(source.device().clone(), queue.family())?;
let mut cbb = AutoCommandBufferBuilder::primary(
source.device().clone(),
queue.family(),
CommandBufferUsage::MultipleSubmit,
)?;
cbb.copy_buffer_to_image_dimensions(
source,
init,

View File

@ -206,7 +206,7 @@ impl<'a> DeviceMemoryBuilder<'a> {
}
// Private function -- no doc comment needed! Copied shamelessly and poorly from Ash.
fn push_next<T: ExtendsMemoryAllocateInfo>(mut self, next: &mut T) -> DeviceMemoryBuilder<'a> {
fn push_next<T: ExtendsMemoryAllocateInfo>(self, next: &mut T) -> DeviceMemoryBuilder<'a> {
unsafe {
let next_ptr = next as *mut T as *mut BaseOutStructure;
let mut prev = self.allocate.pNext as *mut BaseOutStructure;

View File

@ -7,14 +7,7 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use std::error;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::mem::MaybeUninit;
use std::ptr;
use std::sync::Arc;
use crate::check_errors;
use crate::descriptor::descriptor::DescriptorDesc;
use crate::descriptor::descriptor_set::UnsafeDescriptorSetLayout;
use crate::descriptor::pipeline_layout::PipelineLayout;
@ -25,18 +18,23 @@ use crate::descriptor::pipeline_layout::PipelineLayoutDescPcRange;
use crate::descriptor::pipeline_layout::PipelineLayoutNotSupersetError;
use crate::descriptor::pipeline_layout::PipelineLayoutSuperset;
use crate::descriptor::pipeline_layout::PipelineLayoutSys;
use crate::device::Device;
use crate::device::DeviceOwned;
use crate::pipeline::cache::PipelineCache;
use crate::pipeline::shader::EntryPointAbstract;
use crate::pipeline::shader::SpecializationConstants;
use crate::check_errors;
use crate::device::Device;
use crate::device::DeviceOwned;
use crate::vk;
use crate::Error;
use crate::OomError;
use crate::SafeDeref;
use crate::VulkanObject;
use std::error;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::mem::MaybeUninit;
use std::ptr;
use std::sync::Arc;
/// A pipeline object that describes to the Vulkan implementation how it should perform compute
/// operations.
@ -409,6 +407,7 @@ mod tests {
use crate::buffer::BufferUsage;
use crate::buffer::CpuAccessibleBuffer;
use crate::command_buffer::AutoCommandBufferBuilder;
use crate::command_buffer::CommandBufferUsage;
use crate::descriptor::descriptor::DescriptorBufferDesc;
use crate::descriptor::descriptor::DescriptorDesc;
use crate::descriptor::descriptor::DescriptorDescTy;
@ -555,9 +554,12 @@ mod tests {
.build()
.unwrap();
let mut cbb =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap();
let mut cbb = AutoCommandBufferBuilder::primary(
device.clone(),
queue.family(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
cbb.dispatch([1, 1, 1], pipeline.clone(), set, (), vec![])
.unwrap();
let cb = cbb.build().unwrap();