What Is the Difference Between std140 and std430?
In GLSL (OpenGL Shading Language), std140 and
std430 are standard memory layout qualifiers that define
how data structures are aligned and padded in GPU memory buffers. While
std140 enforces strict 16-byte alignment rules across
arrays and structures for Uniform Buffer Objects (UBOs),
std430 provides a tighter, more cache-friendly layout
designed specifically for Shader Storage Buffer Objects (SSBOs).
Understanding the differences between these two layouts is essential for
ensuring that host application memory (such as C++ structs) matches the
layout expected by GPU shaders without corrupting data or introducing
unnecessary padding.
Buffer Compatibility
The primary functional difference between the two memory layouts lies in where they can be legally used:
- std140: Introduced in OpenGL 3.1,
std140is the standard layout for Uniform Buffer Objects (UBOs). It can also be applied to Shader Storage Buffer Objects (SSBOs), ensuring backward compatibility and cross-buffer layout consistency. - std430: Introduced in OpenGL 4.3 alongside SSBOs,
std430is valid only for SSBOs. It cannot be used for standard Uniform Buffer Objects.
Alignment and Padding Rules
Both layouts align fundamental types like float,
int, vec2, and vec4 to multiples
of their natural size (e.g., a float aligns to 4 bytes, a
vec2 to 8 bytes, and a vec4 to 16 bytes). The
major divergence occurs when handling arrays and nested structures.
Arrays and Array Elements
- std140: Every element in an array is rounded up to
the size of a
vec4(16 bytes), regardless of the actual data type. For example, an array of scalars likefloat values[4]consumes 64 bytes instd140because eachfloatis padded to 16 bytes (equivalent to a 16-byte stride). - std430: Array elements retain their natural base
alignment. A
float values[4]array instd430occupies 16 contiguous bytes (4 bytes per element), and avec2 coords[4]array occupies 32 bytes (8 bytes per element).
Structures and Nested Types
- std140: The base alignment of a struct is rounded
up to a multiple of 16 bytes (
vec4size). Any array of structs will also have its stride padded to a multiple of 16 bytes. - std430: A struct's alignment is determined solely
by the largest base alignment of any of its member variables. If a
struct contains only
floatandvec2members, its alignment remains 8 bytes rather than being forced to 16 bytes.
Comparison Summary
| Feature | std140 | std430 |
|---|---|---|
| Supported Buffers | Uniform Buffer Objects (UBOs), SSBOs | Shader Storage Buffer Objects (SSBOs) only |
| Scalar Array Stride | Padded to 16 bytes per element | Natural alignment (4 bytes for
float/int) |
| Vector Array Stride | Always rounded up to 16 bytes | Matches vector size (vec2 = 8 bytes, vec4
= 16 bytes) |
| Struct Alignment | Always rounded up to a multiple of 16 bytes | Largest member's natural alignment |
| Memory Efficiency | Lower (higher padding overhead) | Higher (compact packing) |
Practical Host-Side Matching
When setting up data on the CPU in languages like C or C++, matching
std430 is generally simpler because standard C++ struct
packing rules closely resemble std430 natural alignment. In
contrast, mapping data for a std140 buffer often requires
explicit manual padding or alignment attributes (such as
alignas(16)) to account for forced 16-byte boundaries on
array elements and nested structs.