Skip to main content

What Direct3D 10 Is All About

Geometry Shaders And Stream Output

Taken from "The Direct3D 10 System" by David Blythe

Last but not least, we will talk about the newest part of the core: the Geometry Shader (GS). Let's work our way through the logical steps of the rendering process (this could be fixed function or threaded via a fragmented core). The term "pipeline" is only taxonomy; each stage is a part of the process, but it could be happening at the same time another part of the same frame is being worked on somewhere else. However, the first place data goes is the Input Assembler (IA).

As you can see from the diagram above, the IA collects one-dimensional vertex data. Each of the (up to) eight input streams has specific vertex data containing up to 16 structural fields called elements. Each element is a multiple of one to four data items. Looking again at the diagram above, you can see the vertex data input as 16x3x32b (e.g., float32s).

Traditionally, the vertex data is read in sequence from the vertex buffer, but an index buffer can be specified. This provides for additional performance optimizations, as the recompilation of results for the same index can be avoided. Each piece is tagged and worked on separately, and then put together later according to the index address assigned.

The IA can also replicate objects; I referred to this earlier as instancing. At the same time, each primitive data item is "tagged" with a current instance, primitive and vertex ID. Each object now has an index ID that can be accessed in later stages. This means that, for example, one tank in your battle game can become 100, each with its own properties and ID. Here, one draw call can handle hundred objects, where it once took an individual draw call for each.

Taken from "The Direct3D 10 System" by David Blythe

From the VS, data moves to the newest parts of the process, the Geometry Shader and Stream Output (SO). The GS takes all of the vertices (points, lines, and triangles) and can add to them. In fact, the GS can magnify the number of input primitives by producing additional primitives: up to 1024 32-bit values of vertex data. This is the most powerful part of the core, in that the GS can also attach more attributes to the vertex data - or destroy it.

The Geometry Shader is so powerful because it is the only shader that can write to memory, which it does via Stream Output. It copies either one multi-element (up to 16 elements) or up to four single-element output streams to output buffers. This data can be read back into the process by any part of the process, meaning that data could stop coming from the IA and Vertex Shader. Scenes could be sustained entirely by manipulations of output data.

From: "The Direct3D 10 System" by David Blythe

The rest of the process is familiar to us. The data travels a setup stage, where rasterizer and some early Z-culling are accomplished. The Pixel Shaders then take the data and attach the skin to the wire frame. This includes lighting and other techniques to make our games look amazing.