Guide to gl_PrimitiveLineIndicesEXT in Mesh Shaders
In GLSL mesh shaders utilizing the GL_EXT_mesh_shader
extension, gl_PrimitiveLineIndicesEXT is a built-in output
array used to define line topology. When a mesh shader is configured to
output lines instead of triangles or points, this array specifies the
index pairs that connect vertices together into distinct line
primitives. This article explains the purpose, declaration, and
mechanics of using gl_PrimitiveLineIndicesEXT to construct
indexed line geometry directly on the GPU.
The Role of gl_PrimitiveLineIndicesEXT
Mesh shaders operate by decoupling per-vertex data generation from primitive assembly. Rather than relying on a fixed-function primitive assembler, the mesh shader explicitly produces a list of output vertices and an index list specifying how those vertices assemble into primitives.
When generating line primitives, each line requires exactly two
vertex indices. The gl_PrimitiveLineIndicesEXT built-in
array serves as the primitive index buffer. Each element in the array
represents an individual line segment and points to two vertices
generated within the same mesh shader workgroup.
Declaration and Type
The array is available when the mesh shader defines its primitive
output type as lines:
#extension GL_EXT_mesh_shader : require
layout(lines) out;
layout(max_vertices = 64, max_primitives = 64) out;Under this layout, the shader runtime provides the built-in output:
out uvec2 gl_PrimitiveLineIndicesEXT[];The array size corresponds to the max_primitives value
declared in the layout. Each element is a two-component unsigned integer
vector (uvec2), where the x and y
components represent the zero-based indices of the start and end
vertices stored in the vertex output arrays (such as
gl_MeshVerticesEXT).
How It Works in Practice
During execution, a mesh shader workgroup calculates per-vertex
attributes and writes them into output arrays indexed from
0 to vertex_count - 1. Concurrently, threads
assign connectivity by writing to
gl_PrimitiveLineIndicesEXT.
For example, to draw a connected line strip between three generated vertices:
// Define 3 vertices
SetMeshOutputsEXT(3, 2);
// Write vertex positions into gl_MeshVerticesEXT...
// Define primitive indices
gl_PrimitiveLineIndicesEXT[0] = uvec2(0, 1); // Line 0 connects vertex 0 to vertex 1
gl_PrimitiveLineIndicesEXT[1] = uvec2(1, 2); // Line 1 connects vertex 1 to vertex 2Key Benefits
- Vertex Reuse: Without an index array, shared
vertices along connected paths or wireframe networks would have to be
duplicated.
gl_PrimitiveLineIndicesEXTallows adjacent lines to reference the same vertex, reducing vertex attribute calculations and memory footprint within the workgroup. - Dynamic Topology: The shader can compute arbitrary line topologies on the fly—such as wireframe overlays, vector field visualizers, hair strands, or dynamic debug bounding boxes—without requiring pre-assembled index buffers from the CPU.
- Hardware Efficiency: Modern GPU hardware uses these indices directly to schedule rasterization for wide or anti-aliased lines without routing primitive assembly through fixed-function geometry pipeline stages.