![]() |
CUGL 4.0
Cornell University Game Library
|
#include <CUStorageBuffer.h>
Public Member Functions | |
| StorageBuffer () | |
| ~StorageBuffer () | |
| void | dispose () |
| template<typename T > | |
| bool | init (size_t capacity, BufferAccess access=BufferAccess::COMPUTE_ALL) |
| template<typename T > | |
| bool | init (size_t capacity, Uint32 blocks, BufferAccess access=BufferAccess::COMPUTE_ALL) |
| bool | initWithStride (size_t capacity, size_t stride, BufferAccess access=BufferAccess::DYNAMIC) |
| bool | initWithStride (size_t capacity, size_t stride, Uint32 blocks, BufferAccess access=BufferAccess::DYNAMIC) |
| BufferData * | getImplementation () |
| BufferAccess | getAccess () const |
| void | setName (std::string name) |
| const std::string | getName () const |
| size_t | getItemSize () const |
| size_t | getCapacity () const |
| Uint32 | getBlockCount () const |
| size_t | getBlockStride () const |
| size_t | loadData (const std::byte *data, size_t amt) |
| template<typename T > | |
| bool | loadData (const T *data, size_t size) |
| template<typename T > | |
| bool | loadData (const std::vector< T > &data) |
| size_t | loadBlock (Uint32 block, const std::byte *data, size_t amt) |
| template<typename T > | |
| size_t | loadBlock (Uint32 block, const T *data, size_t size) |
| template<typename T > | |
| size_t | loadBlock (Uint32 block, const std::vector< T > &data) |
| size_t | readData (std::byte *data, size_t size) |
| template<typename T > | |
| size_t | readData (T *data, size_t size) |
| template<typename T > | |
| size_t | readData (std::vector< T > &data) |
| size_t | readBlock (Uint32 block, std::byte *data, size_t amt) |
| template<typename T > | |
| size_t | readBlock (Uint32 block, T *data, size_t amt) |
| template<typename T > | |
| size_t | readBlock (Uint32 block, std::vector< T > &data) |
| void | flush () |
Static Public Member Functions | |
| template<typename T > | |
| static std::shared_ptr< StorageBuffer > | alloc (size_t capacity, BufferAccess access=BufferAccess::COMPUTE_ALL) |
| template<typename T > | |
| static std::shared_ptr< StorageBuffer > | alloc (size_t capacity, Uint32 blocks, BufferAccess access=BufferAccess::COMPUTE_ALL) |
| static std::shared_ptr< StorageBuffer > | allocWithStride (size_t size, size_t stride, BufferAccess access=BufferAccess::DYNAMIC) |
| static std::shared_ptr< StorageBuffer > | allocWithStride (size_t size, size_t stride, Uint32 blocks, BufferAccess access=BufferAccess::DYNAMIC) |
This class is a Vulkan storage buffer
Storage buffers are a slower form of uniform buffer that can support large arrays of data. They are only supported in Vulkan. Attempts to initialize an object of this class in OpenGL will fail.
Like UniformBuffer, a storage buffer can be broken into multiple blocks. However, this feature is less useful as storage buffers are themselves arrays of data. Blocks are primarily useful with buffers that have access BufferAccess::STATIC.
Unlike a UniformBuffer, storage buffers use std430 formatting. This requires less padding in the associated data structures.
| cugl::graphics::StorageBuffer::StorageBuffer | ( | ) |
Creates an uninitialized storage buffer.
You must initialize the storage buffer to allocate memory.
|
inline |
Deletes this storage buffer, disposing all resources.
|
inlinestatic |
Returns a newly allocated storage buffer with a block of the given capacity.
This storage buffer will only support a single block. Unlike a uniform buffer, this buffer is in std430. The element stride is computed from the type T.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| capacity | The maximum elements of bytes per block |
| access | The buffer access |
|
inlinestatic |
Returns a newly allocated storage buffer with multiple blocks of the given capacity.
Unlike a uniform buffer, this buffer is in std430. The element stride is computed from the type T. However the blocks must still be aligned, and so this may take significantly more memory than the number of blocks times the capacity. If the graphics card cannot support that many blocks, this method will return false.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| capacity | The maximum number of elements per block |
| blocks | The number of blocks to support |
| access | The buffer access |
|
inlinestatic |
Returns a newly allocated storage buffer with a block of the given capacity and stride.
This storage buffer will only support a single block. Unlike a uniform buffer, this buffer is in std430. The value stride is used to indicate the size of a single element. The byte size is the capacity times the stride.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| size | The maximum number of elements in a block |
| stride | The element stride |
| access | The buffer access |
|
inlinestatic |
Initializes this storage buffer with blocks of the given size and stride.
The value stride is used to indicate the size of a single element. The byte size is capacity times stride.
Unlike a uniform buffer, this buffer is in std430. However the blocks must still be aligned, and so this may take significantly more memory than the number of blocks times the block size. If the graphics card cannot support that many blocks, this method will return false.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| size | The maximum number of elements in a block |
| stride | The element stride |
| blocks | The number of blocks to support |
| access | The buffer access |
| void cugl::graphics::StorageBuffer::dispose | ( | ) |
Deletes the storage buffer, freeing all resources.
You must reinitialize the storage buffer to use it.
| void cugl::graphics::StorageBuffer::flush | ( | ) |
Flushes any changes to the graphics card.
For any method other than loadData, changes to this storage buffer are only applied to a backing buffer in CPU memory, and are not reflected on the graphics card. This method synchronizes these two memory regions.
|
inline |
Returns the access policy of this storage buffer
|
inline |
Returns the number of blocks supported by this buffer.
A storage buffer can support multiple storage blocks at once.
|
inline |
Returns the stride of a single block in this storage buffer.
The stride measures the alignment (in bytes) of a block. It is at least as large as the block capacity, but may be more due to alignment issues
|
inline |
Returns the capacity of a single block in this storage buffer.
The capacity is number of elements that may be stored in a single block. This value is not measured in bytes. To get the value in bytes, mutliply this result by getItemSize.
|
inline |
Returns the platform-specific implementation for this buffer
The value returned is an opaque type encapsulating the information for either OpenGL or Vulkan.
|
inline |
Returns the size of a single element in this storage buffer.
A storage buffer is essentially an array of elements. All elements must have the same size (in bytes), as specified by this method. Templated methods such as loadData should agree with this size.
|
inline |
Returns the name of this storage buffer.
A name is a user-defined way of identifying a buffer. It is typically the appropriate shader variable name, but this is not necessary for it to function properly.
|
inline |
Initializes this storage buffer to support a block of the given capacity.
This storage buffer will only support a single block. Unlike a uniform buffer, this buffer is in std430. The element stride is computed from the type T.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| capacity | The number of elements in this buffer |
| access | The buffer access |
|
inline |
Initializes this storage buffer to support multiple blocks of the given capacity.
Unlike a uniform buffer, this buffer is in std430. The element stride is computed from the type T. However the blocks must still be aligned, and so this may take significantly more memory than the number of blocks times the capacity. If the graphics card cannot support that many blocks, this method will return false.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| capacity | The maximum number of elements per block |
| blocks | The number of blocks to support |
| access | The buffer access |
|
inline |
Initializes this storage buffer with one block of the given capacity and stride.
This storage buffer will only support a single block. Unlike a uniform buffer, this buffer is in std430. The value stride is used to indicate the size of a single element. The byte size is the capacity times the stride.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| capacity | The number of elements in the buffer |
| stride | The element stride |
| access | The buffer access |
| bool cugl::graphics::StorageBuffer::initWithStride | ( | size_t | capacity, |
| size_t | stride, | ||
| Uint32 | blocks, | ||
| BufferAccess | access = BufferAccess::DYNAMIC |
||
| ) |
Initializes this storage buffer with blocks of the given capacity and stride.
The value stride is used to indicate the size of a single element. The byte size is capacity times stride.
Unlike a uniform buffer, this buffer is in std430. However the blocks must still be aligned, and so this may take significantly more memory than the number of blocks times the block size. If the graphics card cannot support that many blocks, this method will return false.
Note that some access types such as BufferAccess#STATIC or BufferAccess#COMPUTE_ONLY can only be updated once. Any attempts to load data after the first time will fail.
| capacity | The maximum number of elements per block |
| stride | The element stride |
| blocks | The number of blocks to support |
| access | The buffer access |
| size_t cugl::graphics::StorageBuffer::loadBlock | ( | Uint32 | block, |
| const std::byte * | data, | ||
| size_t | amt | ||
| ) |
Loads the given data in to the specified block
The value amt must be less than or equal to the size of block. Calling this method will update the CPU memory, but not update it on the GPU. You must call flush to synchronize the buffer.
If the storage buffer has more than one block, this method will fail on any storage buffer that does not have access BufferAccess#STATIC or BufferAccess#COMPUTE_ALL. In addition, for buffers without this access, this method can only be called once.
| block | The block to update |
| data | The data to load |
| amt | The data size in bytes |
|
inline |
Loads the given data in to the specified block
The number of elements in data must be less than or equal to the size of block. Calling this method will update the CPU memory, but not update it on the GPU. You must call flush to synchronize the buffer.
The type T should have size getItemSize. If not, the results of this method are undefined.
If the storage buffer has more than one block, this method will fail on any storage buffer that does not have access BufferAccess#STATIC or BufferAccess#COMPUTE_ALL. In addition, for buffers without this access, this method can only be called once.
| block | The block to update |
| data | The vertices to load |
|
inline |
Loads the given data in to the specified block
The value amt must be less than or equal to the size of block. Calling this method will update the CPU memory, but not update it on the GPU. You must call flush to synchronize the buffer.
The type T should have size getItemSize. If not, the results of this method are undefined.
If the storage buffer has more than one block, this method will fail on any storage buffer that does not have access BufferAccess#STATIC or BufferAccess#COMPUTE_ALL. In addition, for buffers without this access, this method can only be called once.
| block | The block to update |
| data | The vertices to load |
| size | The number of vertices to load |
| size_t cugl::graphics::StorageBuffer::loadData | ( | const std::byte * | data, |
| size_t | amt | ||
| ) |
Loads the given data in to this buffer
This will load memory into the entire buffer, potentially across multiple blocks. It will call flush when done, committing the changes to the graphics card.
If this buffer spans more than one block, each block must align with getBlockStride. That may require padding on the underlying data.
Note that this method may only be called once for buffers with access BufferAccess#STATIC, BufferAccess#COMPUTE_ONLY or BufferAccess#COMPUTE_READ. Additional attempts to load into such buffers will fail.
| data | The data to load |
| amt | The data size in bytes |
|
inline |
Loads the given data in to this buffer
This will load the data structure into the storage buffer. It will call flush when done, committing the changes to the graphics card.
This method is designed for storage buffers with a single block. Due to alignment issues, it does not make sense to use this method on a storage buffer with multiple blocks. Calling this method in that case will fail.
The type T should have size getItemSize. If not, the results of this method are undefined.
Note that this method may only be called once for buffers with access BufferAccess#STATIC, BufferAccess#COMPUTE_ONLY or BufferAccess#COMPUTE_READ. Additional attempts to load into such buffers will fail.
| data | The element array to load |
|
inline |
Loads the given data in to this buffer
This will load the data structure into the storage buffer. It will call flush when done, committing the changes to the graphics card.
This method is designed for storage buffers with a single block. Due to alignment issues, it does not make sense to use this method on a storage buffer with multiple blocks. Calling this method in that case will fail.
The type T should have size getItemSize. If not, the results of this method are undefined.
Note that this method may only be called once for buffers with access BufferAccess#STATIC, BufferAccess#COMPUTE_ONLY or BufferAccess#COMPUTE_READ. Additional attempts to load into such buffers will fail.
| data | The element array to load |
| size | The number of elements to load |
| size_t cugl::graphics::StorageBuffer::readBlock | ( | Uint32 | block, |
| std::byte * | data, | ||
| size_t | amt | ||
| ) |
Reads the specified block into the given array
This method allows us to extract the elements of a storage buffer block into any array on the CPU side. It is generally only useful for buffers of type BufferAccess#COMPUTE_READ or BufferAccess#COMPUTE_ALL so that we can inspect the results of a compute shader.
| block | The block to read from |
| data | The array to receive the data |
| amt | The number of bytes to read |
|
inline |
Reads the specified block into the given vector
This method allows us to extract the elements of a storage buffer block into any array on the CPU side. It is generally only useful for buffers of type BufferAccess#COMPUTE_READ or BufferAccess#COMPUTE_ALL so that we can inspect the results of a compute shader.
The type T should have size getItemSize. If not, the results of this method are undefined.
| block | The block to read from |
| data | The vector to receive the data |
|
inline |
Reads the specified block into the given array
This method allows us to extract the elements of a storage buffer block into any array on the CPU side. It is generally only useful for buffers of type BufferAccess#COMPUTE_READ or BufferAccess#COMPUTE_ALL so that we can inspect the results of a compute shader.
The type T should have size getItemSize. If not, the results of this method are undefined.
| block | The block to read from |
| data | The array to receive the data |
| amt | The number of elements to read |
| size_t cugl::graphics::StorageBuffer::readData | ( | std::byte * | data, |
| size_t | size | ||
| ) |
Reads from the buffer into the given data array.
This method allows us to extract the elements of a storage buffer into any array on the CPU side. It is generally only useful for buffers of type BufferAccess#COMPUTE_READ or BufferAccess#COMPUTE_ALL so that we can inspect the results of a compute shader.
This version will read from all of the blocks in the buffer. If this buffer spans more than one block, each block will align with getBlockStride.
In this version of the method, size is the number of bytes to read.
| data | The array to receive the data |
| size | The number of bytes to read |
|
inline |
Reads from the buffer into the given array.
This method allows us to extract the elements of a storage buffer into any array on the CPU side. It is generally only useful for buffers of type BufferAccess#COMPUTE_READ or BufferAccess#COMPUTE_ALL so that we can inspect the results of a compute shader.
This method is designed for storage buffers with a single block. Due to alignment issues, it does not make sense to use this method on a storage buffer with multiple blocks. Calling this method in that case will fail.
The type T should have size getItemSize. If not, the results of this method are undefined.
| data | The vector to receive the data |
|
inline |
Reads from the buffer into the given array.
This method allows us to extract the elements of a storage buffer into any array on the CPU side. It is generally only useful for buffers of type BufferAccess#COMPUTE_READ or BufferAccess#COMPUTE_ALL so that we can inspect the results of a compute shader.
This method is designed for storage buffers with a single block. Due to alignment issues, it does not make sense to use this method on a storage buffer with multiple blocks. Calling this method in that case will fail.
The type T should have size getItemSize. If not, the results of this method are undefined.
| data | The array to receive the data |
| size | The number of elements to read |
|
inline |
Sets the name of this storage buffer.
A name is a user-defined way of identifying a buffer. It is typically the appropriate shader variable name, but this is not necessary for it to function properly.
| name | The name of this storage buffer. |