CUGL 4.0
Cornell University Game Library
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | List of all members
cugl::graphics::StorageBuffer Class Reference

#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< StorageBufferalloc (size_t capacity, BufferAccess access=BufferAccess::COMPUTE_ALL)
 
template<typename T >
static std::shared_ptr< StorageBufferalloc (size_t capacity, Uint32 blocks, BufferAccess access=BufferAccess::COMPUTE_ALL)
 
static std::shared_ptr< StorageBufferallocWithStride (size_t size, size_t stride, BufferAccess access=BufferAccess::DYNAMIC)
 
static std::shared_ptr< StorageBufferallocWithStride (size_t size, size_t stride, Uint32 blocks, BufferAccess access=BufferAccess::DYNAMIC)
 

Detailed Description

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.

Constructor & Destructor Documentation

◆ StorageBuffer()

cugl::graphics::StorageBuffer::StorageBuffer ( )

Creates an uninitialized storage buffer.

You must initialize the storage buffer to allocate memory.

◆ ~StorageBuffer()

cugl::graphics::StorageBuffer::~StorageBuffer ( )
inline

Deletes this storage buffer, disposing all resources.

Member Function Documentation

◆ alloc() [1/2]

template<typename T >
static std::shared_ptr< StorageBuffer > cugl::graphics::StorageBuffer::alloc ( size_t  capacity,
BufferAccess  access = BufferAccess::COMPUTE_ALL 
)
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.

Parameters
capacityThe maximum elements of bytes per block
accessThe buffer access
Returns
a newly allocated storage buffer with a block of the given capacity.

◆ alloc() [2/2]

template<typename T >
static std::shared_ptr< StorageBuffer > cugl::graphics::StorageBuffer::alloc ( size_t  capacity,
Uint32  blocks,
BufferAccess  access = BufferAccess::COMPUTE_ALL 
)
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.

Parameters
capacityThe maximum number of elements per block
blocksThe number of blocks to support
accessThe buffer access
Returns
a newly allocated storage buffer with multiple blocks of the given capacity.

◆ allocWithStride() [1/2]

static std::shared_ptr< StorageBuffer > cugl::graphics::StorageBuffer::allocWithStride ( size_t  size,
size_t  stride,
BufferAccess  access = BufferAccess::DYNAMIC 
)
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.

Parameters
sizeThe maximum number of elements in a block
strideThe element stride
accessThe buffer access
Returns
true if initialization was successful.

◆ allocWithStride() [2/2]

static std::shared_ptr< StorageBuffer > cugl::graphics::StorageBuffer::allocWithStride ( size_t  size,
size_t  stride,
Uint32  blocks,
BufferAccess  access = BufferAccess::DYNAMIC 
)
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.

Parameters
sizeThe maximum number of elements in a block
strideThe element stride
blocksThe number of blocks to support
accessThe buffer access
Returns
true if initialization was successful.

◆ dispose()

void cugl::graphics::StorageBuffer::dispose ( )

Deletes the storage buffer, freeing all resources.

You must reinitialize the storage buffer to use it.

◆ flush()

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.

◆ getAccess()

BufferAccess cugl::graphics::StorageBuffer::getAccess ( ) const
inline

Returns the access policy of this storage buffer

Returns
the access policy of this storage buffer

◆ getBlockCount()

Uint32 cugl::graphics::StorageBuffer::getBlockCount ( ) const
inline

Returns the number of blocks supported by this buffer.

A storage buffer can support multiple storage blocks at once.

Returns
the number of blocks supported by this buffer.

◆ getBlockStride()

size_t cugl::graphics::StorageBuffer::getBlockStride ( ) const
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

Returns
the stride of a single block in this storage buffer.

◆ getCapacity()

size_t cugl::graphics::StorageBuffer::getCapacity ( ) const
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.

Returns
the capacity of a single block in this storage buffer.

◆ getImplementation()

BufferData * cugl::graphics::StorageBuffer::getImplementation ( )
inline

Returns the platform-specific implementation for this buffer

The value returned is an opaque type encapsulating the information for either OpenGL or Vulkan.

Returns
the platform-specific implementation for this buffer

◆ getItemSize()

size_t cugl::graphics::StorageBuffer::getItemSize ( ) const
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.

Returns
the size of a single element in this storage buffer.

◆ getName()

const std::string cugl::graphics::StorageBuffer::getName ( ) const
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.

Returns
the name of this storage buffer.

◆ init() [1/2]

template<typename T >
bool cugl::graphics::StorageBuffer::init ( size_t  capacity,
BufferAccess  access = BufferAccess::COMPUTE_ALL 
)
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.

Parameters
capacityThe number of elements in this buffer
accessThe buffer access
Returns
true if initialization was successful.

◆ init() [2/2]

template<typename T >
bool cugl::graphics::StorageBuffer::init ( size_t  capacity,
Uint32  blocks,
BufferAccess  access = BufferAccess::COMPUTE_ALL 
)
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.

Parameters
capacityThe maximum number of elements per block
blocksThe number of blocks to support
accessThe buffer access
Returns
true if initialization was successful.

◆ initWithStride() [1/2]

bool cugl::graphics::StorageBuffer::initWithStride ( size_t  capacity,
size_t  stride,
BufferAccess  access = BufferAccess::DYNAMIC 
)
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.

Parameters
capacityThe number of elements in the buffer
strideThe element stride
accessThe buffer access
Returns
true if initialization was successful.

◆ initWithStride() [2/2]

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.

Parameters
capacityThe maximum number of elements per block
strideThe element stride
blocksThe number of blocks to support
accessThe buffer access
Returns
true if initialization was successful.

◆ loadBlock() [1/3]

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.

Parameters
blockThe block to update
dataThe data to load
amtThe data size in bytes
Returns
the number of bytes loaded

◆ loadBlock() [2/3]

template<typename T >
size_t cugl::graphics::StorageBuffer::loadBlock ( Uint32  block,
const std::vector< T > &  data 
)
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.

Parameters
blockThe block to update
dataThe vertices to load
Returns
the number of bytes loaded

◆ loadBlock() [3/3]

template<typename T >
size_t cugl::graphics::StorageBuffer::loadBlock ( Uint32  block,
const T data,
size_t  size 
)
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.

Parameters
blockThe block to update
dataThe vertices to load
sizeThe number of vertices to load
Returns
the number of bytes loaded

◆ loadData() [1/3]

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.

Parameters
dataThe data to load
amtThe data size in bytes
Returns
the number of bytes loaded

◆ loadData() [2/3]

template<typename T >
bool cugl::graphics::StorageBuffer::loadData ( const std::vector< T > &  data)
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.

Parameters
dataThe element array to load
Returns
true if the data was successfully loaded

◆ loadData() [3/3]

template<typename T >
bool cugl::graphics::StorageBuffer::loadData ( const T data,
size_t  size 
)
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.

Parameters
dataThe element array to load
sizeThe number of elements to load
Returns
true if the data was successfully loaded

◆ readBlock() [1/3]

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.

Parameters
blockThe block to read from
dataThe array to receive the data
amtThe number of bytes to read
Returns
the number of bytes read

◆ readBlock() [2/3]

template<typename T >
size_t cugl::graphics::StorageBuffer::readBlock ( Uint32  block,
std::vector< T > &  data 
)
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.

Parameters
blockThe block to read from
dataThe vector to receive the data
Returns
the number of elements read

◆ readBlock() [3/3]

template<typename T >
size_t cugl::graphics::StorageBuffer::readBlock ( Uint32  block,
T data,
size_t  amt 
)
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.

Parameters
blockThe block to read from
dataThe array to receive the data
amtThe number of elements to read
Returns
the number of elements read

◆ readData() [1/3]

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.

Parameters
dataThe array to receive the data
sizeThe number of bytes to read
Returns
the number of bytes read

◆ readData() [2/3]

template<typename T >
size_t cugl::graphics::StorageBuffer::readData ( std::vector< T > &  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.

Parameters
dataThe vector to receive the data
Returns
the number of elements read

◆ readData() [3/3]

template<typename T >
size_t cugl::graphics::StorageBuffer::readData ( T data,
size_t  size 
)
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.

Parameters
dataThe array to receive the data
sizeThe number of elements to read
Returns
the number of elements read

◆ setName()

void cugl::graphics::StorageBuffer::setName ( std::string  name)
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.

Parameters
nameThe name of this storage buffer.

The documentation for this class was generated from the following file: