Commands that the GPU will execute (includes draw commands).
With Vulkan, before the GPU can do anything you must create a
CommandBuffer. A command buffer
is a list of commands that will executed by the GPU. Once a command buffer is created, you can
execute it. A command buffer must always be created even for the most simple tasks.
There are three types of command buffers:
- Primary command buffers. They can contain any command. They are the only type of command buffer that can be submitted to a queue.
- Secondary “graphics” command buffers. They can only contain draw and clear commands. They can only be called from a primary command buffer when inside a render pass.
- Secondary “compute” command buffers. They can only contain non-render-pass-related commands (ie. everything but drawing, clearing, etc.) and cannot enter a render pass. They can only be called from a primary command buffer outside of a render pass.
Using secondary command buffers leads to slightly lower performance on the GPU, but they have two advantages on the CPU side:
- Building a command buffer is a single-threaded operation, but by using secondary command buffers you can build multiple secondary command buffers in multiple threads simultaneously.
- Secondary command buffers can be kept alive between frames. When you always repeat the same operations, it might be a good idea to build a secondary command buffer once at initialization and then reuse it afterwards.
The most basic (and recommended) way to create a command buffer is to create a
AutoCommandBufferBuilder, then record commands to it.
When you are done adding commands, build it to obtain either a
Once built, use the
PrimaryCommandBufferAbstract trait to submit the command buffer.
Submitting a command buffer returns an object that implements the
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::PrimaryCommandBufferAbstract; use vulkano::command_buffer::SubpassContents; let cb = AutoCommandBufferBuilder::primary( &command_buffer_allocator, queue.queue_family_index(), CommandBufferUsage::MultipleSubmit ).unwrap() .begin_render_pass(render_pass_begin_info, SubpassContents::Inline).unwrap() .bind_pipeline_graphics(graphics_pipeline.clone()) .bind_vertex_buffers(0, vertex_buffer.clone()) .draw(vertex_buffer.len() as u32, 1, 0, 0).unwrap() .end_render_pass().unwrap() .build().unwrap(); let _future = cb.execute(queue.clone());
commands_extra modules contain structs that correspond to various
commands that can be added to command buffer builders. A command can be added to a command
buffer builder by using the
AddCommand<C> trait, where
C is the command struct.
AutoCommandBufferBuilder internally uses a
UnsafeCommandBufferBuilder wrapped around
multiple layers. See the
cb module for more information.
Command pools are automatically handled by default, but vulkano also allows you to use
alternative command pool implementations and use them. See the
pool module for more
StandardCommandBufferAllocatordon’t implement the
Synctraits. If you use this allocator, then the
AutoCommandBufferBuilderwill not implement
Synceither. Once a command buffer is built, however, it does implement