Geometry Shader (GS) stage

The Geometry Shader (GS) stage processes entire primitives: triangles, lines, and points, along with their adjacent vertices. It is useful for algorithms including Point Sprite Expansion, Dynamic Particle Systems, and Shadow Volume Generation. It supports geometry amplification and de-amplification.

Purpose and uses

The Geometry Shader stage processes entire primitives: triangles (3 vertices with up to 3 adjacent vertices), lines (2 vertices with up to 2 adjacent vertices), and points (1 vertex).

illustration of a triangle and a line with adjacent vertices

The Geometry Shader also supports limited geometry amplification and de-amplification. Given an input primitive, the Geometry Shader can discard the primitive, or emit one or more new primitives.

The Geometry Shader (GS) stage is a programmable-shader stage; it is shown as a rounded block in the graphics pipeline diagram. This shader stage exposes its own unique functionality, built on the shader models (see common-shader core).

The Geometry Shader stage is well-suited for algorithms including:

  • Point Sprite Expansion
  • Dynamic Particle Systems
  • Fur/Fin Generation
  • Shadow Volume Generation
  • Single Pass Render-to-Cubemap
  • Per-Primitive Material Swapping
  • Per-Primitive Material Setup - This capability includes generation of barycentric coordinates as primitive data so that a pixel shader can perform custom attribute interpolation.

Input

The Geometry Shader stage runs application-specified shader code with entire primitives as input and the ability to generate vertices on output. Unlike vertex shaders, which operate on a single vertex, the geometry shader's inputs are the vertices for a full primitive (three vertices for triangles, two vertices for lines, or single vertex for point). Geometry shaders can also bring in the vertex data for the edge-adjacent primitives as input (an additional three for a triangle, an additional two vertices for a line).

The Geometry Shader stage can consume the SV_PrimitiveID system-generated value that is auto-generated by the Input Assembler (IA) stage. This allows per-primitive data to be fetched or computed if desired.

When a geometry shader is active, it is invoked once for every primitive passed down or generated earlier in the pipeline. Each invocation of the geometry shader sees as input the data for the invoking primitive, whether that is a single point, a single line, or a single triangle. A triangle strip from earlier in the pipeline would result in an invocation of the geometry shader for each individual triangle in the strip (as if the strip were expanded out into a triangle list). All the input data for each vertex in the individual primitive is available (that is, 3 vertices for a triangle), plus adjacent vertex data if applicable and available.

Common vertex abbreviations:

Abbreviation Term
TV Triangle vertex
LV Line vertex
AV Adjacent vertex

 

Output

The Geometry Shader (GS) stage is capable of outputting multiple vertices forming a single selected topology. Available geometry shader output topologies are tristrip, linestrip, and pointlist. The number of primitives emitted can vary freely within any invocation of the geometry shader, though the maximum number of vertices that could be emitted must be declared statically. Strip lengths emitted from a geometry shader invocation can be arbitrary, and new strips can be created via the RestartStrip HLSL function.

Execution of a geometry shader instance is atomic from other invocations, except that data added to the streams is serial. The outputs of a given invocation of a geometry shader are independent of other invocations (though ordering is respected). A geometry shader generating triangle strips will start a new strip on every invocation.

Geometry shader output may be fed to the rasterizer stage and/or to a vertex buffer in memory via the stream output stage. Output fed to memory is expanded to individual point/line/triangle lists (exactly as they would be passed to the rasterizer).

A geometry shader outputs data one vertex at a time by appending vertices to an output stream object. The topology of the streams is determined by a fixed declaration, choosing a TriangleStream, LineStream and PointStream as the output for the GS stage.

There are three types of stream objects available: TriangleStream, LineStream and PointStream, which are all templated objects. The topology of the output is determined by their respective object type, while the format of the vertices appended to the stream is determined by the template type.

When a geometry shader output is identified as a System Interpreted Value (for example, SV_RenderTargetArrayIndex or SV_Position), hardware looks at this data and performs some behavior dependent on the value, in addition to being able to pass the data itself to the next shader stage for input. When such data output from the geometry shader has meaning to the hardware on a per-primitive basis (such as SV_RenderTargetArrayIndex or SV_ViewportArrayIndex), rather than on a per-vertex basis (such as SV_ClipDistance[n] or SV_Position), the per-primitive data is taken from the leading vertex emitted for the primitive.

Partially completed primitives could be generated by the geometry shader if the geometry shader ends and the primitive is incomplete. Incomplete primitives are silently discarded. This is similar to the way the IA treats partially completed primitives.

The geometry shader can perform load and texture sampling operations where screen-space derivatives are not required (samplelevel, samplecmplevelzero, samplegrad).

Graphics pipeline