Skip to content

SSBOs

bufferObject.<index> = <totalByteSize>

bufferObject.<index> = <byteSize> <isRelative> <scaleX> <scaleY>

Shader Storage Buffer Objects (or SSBO’s) are buffers that can store large amounts of data between shader invocations, and even between frames. Unlike images, they allow storing arbitrary data types. For more information about the limits of SSBO’s in OpenGL, read the Khronos Wiki. Using SSBOs with Iris requires the SSBO feature flag.

SSBO’s can hold a guaranteed maximum of 128MB, and on most drivers can hold as much as the GPU physically alllows. Iris will give an error and fail to load a shader if allocating an SSBO would otherwise use up too much VRAM.

Fixed Size SSBOs

To define the SSBO with a fixed size, put the following in shaders.properties and replace <totalByteSize> with the total size of the SSBO in bytes and replace <index> with a unique value from 0 to 8.

bufferObject.<index> = <byteSize>

Screen-Sized SSBOs

SSBOs can also be defined as screen-sized (Iris 1.6.6 and later), where their size is relative to the screen dimensions. This is useful for storing data per-pixel. To use this, put the following in shaders.properties.

bufferObject.<index> = <byteSize> <isRelative> <scaleX> <scaleY>

Fill <isRelative> with true, then <scaleX> and <scaleY> define the multipliers for the number of “pixels” in the SSBO relative to each screen dimension (i.e. 1.0 would mean the same dimension as the screen), and <byteSize> defines the number of bytes per “pixel”. The total size of the SSBO is calculated as int(viewWidth * scaleX) * int(viewHeight * scaleY) * byteSize.

Like with fixed sized SSBOs, replace <index> with a unique value from 0 to 8.

Using SSBOs in your shader

To use an SSBO in a shader, you must define it’s layout. Here is an example definition of a SSBO, where bufferName can be any name:

This layout must be the same across all shaders, otherwise the data will get corrupted.

layout(std430, binding = index) buffer bufferName {
vec4 someData; // 16 bytes
float someExtraData; // 4 bytes
};
void main() {
someData = vec4(0); // Other shaders will see this
gl_FragColor = vec4(someExtraData); // Read from any previous shaders, or the previous frame if it was never overwritten
}

You can optionally make all the variables of an SSBO local to avoid redefinitions. To do this, declare an accessor for the SSBO, as the following.

layout(std430, binding = index) buffer bufferName {
vec4 someData; // 16 bytes
float someExtraData; // 4 bytes
} bufferAccess;
void main() {
bufferAccess.someData = vec4(0); // Other shaders will see this
gl_FragColor = vec4(bufferAccess.someExtraData); // Read from any previous shaders, or the previous frame if it was never overwritten
}

Initialization Data File (Iris 1.8+)

bufferObject.<index> = <byteSize> <filePath>

Iris 1.8 adds support for initializing an SSBO with data from a binary file. Simply append the file path to the end of the SSBO declaration in shaders.properties. The value is be initialized at on shader load/reload. This works with only fixed sized SSBOs, and if the size of the file is bigger than the SSBO Iris will throw an error. If the file is smaller than the SSBO, the remaining data in the SSBO will be uninitialized (and is likely to be garbage data).