GLSL layout(xfb_stride) for Transform Feedback
This article examines the role of the
layout(xfb_stride = S) qualifier in OpenGL Shading Language
(GLSL), which explicitly defines the byte stride between consecutive
vertex records in transform feedback buffers. You will learn how this
qualifier functions within the shader, why it is critical for managing
interleaved buffer layouts and custom padding, and the structural rules
governing its use in modern OpenGL pipelines.
Understanding Transform Feedback Layout Qualifiers
Transform feedback allows OpenGL applications to capture vertex or
geometry shader outputs directly into GPU buffer objects before
rasterization. Traditionally, the mapping of captured variables to
buffer offsets and strides was configured entirely on the CPU using
glTransformFeedbackVaryings.
With the introduction of the ARB_enhanced_layouts
extension (core in OpenGL 4.4 and GLSL 4.40), developers can define
transform feedback layout parameters directly inside the shader code
using layout qualifiers such as xfb_buffer,
xfb_offset, and xfb_stride.
The Core Role of
layout(xfb_stride = S)
The qualifier layout(xfb_stride = S) sets the explicit
distance in bytes between the start of one captured vertex record and
the start of the next in a specified transform feedback buffer. Here,
S is an unsigned integer representing the byte count.
Its primary functions include:
- Defining Interleaved Buffer Strides: When multiple
shader outputs are written to the same buffer index
(
xfb_buffer),xfb_stridedefines the complete size of the combined vertex structure. This ensures each write cycle advances the write pointer by the exact byte length of the interleaved record. - Adding Explicit Padding: If your application
requires data structures aligned to specific byte boundaries (such as
16-byte alignment for SIMD operations or specific uniform/storage block
standards),
xfb_strideallows you to introduce trailing padding beyond the total byte size of the captured components. - Synchronizing CPU and GPU Structures: Setting an explicit stride in GLSL ensures the generated memory layout matches the corresponding C/C++ struct layout on the host side without relying on driver-specific automatic packing.
Syntax and Implementation Rules
The xfb_stride qualifier is assigned to a specific
buffer index and must adhere to several validation rules:
- Multiple of Four: The stride value
Smust be a multiple of 4 bytes. - Sufficient Capacity:
Smust be greater than or equal to the highest component offset written to that buffer plus the size of that component. In other words, variables cannot overlap outside the designated stride. - Consistency per Buffer: All declarations targeting
the same
xfb_bufferindex within the same shader stage must specify the identicalxfb_stridevalue.
The qualifier can be declared globally for an entire buffer index or attached directly to output variables:
#version 440 core
// Globally specify that buffer 0 advances 32 bytes per vertex
layout(xfb_buffer = 0, xfb_stride = 32) out;
// Output 1: 12 bytes (vec3), starts at offset 0
layout(xfb_buffer = 0, xfb_offset = 0) out vec3 outPosition;
// Output 2: 16 bytes (vec4), starts at offset 16 (leaving 4 bytes of padding between position and color)
layout(xfb_buffer = 0, xfb_offset = 16) out vec4 outColor;In this setup, each vertex consumes 32 bytes in Buffer 0:
- Bytes
0–11:outPosition - Bytes
12–15: Unused padding - Bytes
16–31:outColor
The write pointer will increment by exactly 32 bytes for each processed vertex.
Explicit vs. Implicit Strides
If you omit xfb_stride while specifying explicit
xfb_offset values, the driver will not automatically infer
the stride; you must explicitly provide xfb_stride when
manual offsets are used. Conversely, if variables are captured without
explicit offsets, the driver packs variables contiguously and assigns an
implicit stride equal to the total size of the captured components.
Using layout(xfb_stride = S) removes ambiguity, ensuring
deterministic memory layouts across different GPU hardware and driver
implementations.