Expand description
Location in memory that contains data.
A Vulkan buffer is very similar to a buffer that you would use in programming languages in general, in the sense that it is a location in memory that contains data. The difference between a Vulkan buffer and a regular buffer is that the content of a Vulkan buffer is accessible from the GPU.
Vulkano does not perform any specific marshalling of buffer data. The representation of the buffer in
memory is identical between the CPU and GPU. Because the Rust compiler is allowed to reorder struct
fields at will by default when using #[repr(Rust)]
, it is advised to mark each struct requiring
imput assembly as #[repr(C)]
. This forces Rust to follow the standard C procedure. Each element is
laid out in memory in the order of declaration and aligned to a multiple of their alignment.
Various kinds of buffers
The low level implementation of a buffer is UnsafeBuffer
.
This type makes it possible to use all the features that Vulkan is capable of, but as its name
tells it is unsafe to use.
Instead you are encouraged to use one of the high-level wrappers that vulkano provides. Which wrapper to use depends on the way you are going to use the buffer:
- A
DeviceLocalBuffer
designates a buffer usually located in video memory and whose content can’t be directly accessed by your application. Accessing this buffer from the GPU is generally faster compared to accessing a CPU-accessible buffer. - A
CpuBufferPool
is a ring buffer that can be used to transfer data between the CPU and the GPU at a high rate. - A
CpuAccessibleBuffer
is a simple buffer that can be used to prototype.
Here is a quick way to choose which buffer to use. Do you often need to read or write
the content of the buffer? If so, use a CpuBufferPool
. Otherwise, do you need to have access
to the buffer on the CPU? Then use CpuAccessibleBuffer
. Otherwise, use a DeviceLocalBuffer
.
Another example: if a buffer is under constant access by the GPU but you need to
read its content on the CPU from time to time, it may be a good idea to use a
DeviceLocalBuffer
as the main buffer and a CpuBufferPool
for when you need to read it.
Then whenever you need to read the main buffer, ask the GPU to copy from the device-local
buffer to the CPU buffer pool, and read the CPU buffer pool instead.
Buffers usage
When you create a buffer object, you have to specify its usage. In other words, you have to specify the way it is going to be used. Trying to use a buffer in a way that wasn’t specified when you created it will result in a runtime error.
You can use buffers for the following purposes:
- Can contain arbitrary data that can be transferred from/to other buffers and images.
- Can be read and modified from a shader.
- Can be used as a source of vertices and indices.
- Can be used as a source of list of models for draw indirect commands.
Accessing a buffer from a shader can be done in the following ways:
- As a uniform buffer. Uniform buffers are read-only.
- As a storage buffer. Storage buffers can be read and written.
- As a uniform texel buffer. Contrary to a uniform buffer, the data is interpreted by the GPU and can be for example normalized.
- As a storage texel buffer. Additionally, some data formats can be modified with atomic operations.
Using uniform/storage texel buffers requires creating a buffer view. See the view
module
for how to create a buffer view.
Re-exports
pub use self::cpu_access::CpuAccessibleBuffer;
pub use self::cpu_pool::CpuBufferPool;
pub use self::device_local::DeviceLocalBuffer;
pub use self::sys::BufferCreationError;
pub use self::sys::SparseLevel;
Modules
Structs
PhysicalDevice::external_buffer_properties
.Enums
Traits
BufferAccess
. Indicates the type of the content of the buffer.