The Graphics Pipeline in Silicon

You already know the rendering pipeline as a logical assembly line: vertices in, transforms, rasterization, shading, pixels out. Here is the question this whole module answers: where does each of those stages physically live on the chip? Zoom into a die photo of a modern GPU and you will not find seven neat boxes labelled with the pipeline stages. You will find a huge regular field of streaming multiprocessors — the same SMs that run compute kernels — surrounded by a necklace of smaller, odder-looking blocks: rasterizers, texture units, depth units, blenders.

That die photo is the lesson. A "GPU" is not a graphics machine with compute bolted on, nor a compute machine with graphics bolted on. It is a pool of programmable SMs plus a ring of fixed-function accelerators, and the graphics pipeline is a route that data takes through both: programmable stages run as programs on the SMs, fixed-function stages run as dedicated silicon. Learn to see that split and every performance mystery in real-time graphics starts making sense.

Fixed-function or programmable? The stage-by-silicon map

Walk down the logical pipeline and ask, for each stage: is this a circuit or a program?

Logical stageSiliconWhat it physically is
Input assembly (vertex fetch)Fixed-functionA dedicated fetch engine reading index and vertex buffers
Vertex shadingProgrammableYour shader, compiled and dispatched as warps onto the SMs
Clipping, culling, primitive setupFixed-functionHardwired geometry engines
RasterizationFixed-functionParallel edge-function evaluators stamping out pixels
Fragment shadingProgrammableYour shader again — warps on the same SMs
Texture filteringFixed-functionTexture units: address math, fetch and filtering in hardware
Depth testFixed-functionDepth units (early-Z hardware plus the ROPs)
Blending / output (ROP)Fixed-functionRender output units doing read–modify–write on the framebuffer

Notice the shape of the answer: everything that runs your code is the SM pool; everything with a single, unchanging, throughput-critical job is a circuit. The fixed-function blocks are not leftovers from the past — they are deliberate, and the reason why is the deepest idea on this page.

The map, drawn

Step through the picture below. The pipeline reads left to right, but the two dashed stages are not blocks of silicon at all — they are programs, and the arrows dropping out of them show where those programs actually execute: on the one shared SM pool.

The unified-shader revolution

The SM pool was not always a pool. Until about 2006, GPUs had separate vertex units and pixel units — different circuits, with different instruction sets, physically distinct on the die. And that design had a built-in waste problem: a workload is almost never balanced. Render a shadow map (lots of geometry, almost no shading) and the pixel units sat idle; fill the screen with a lush post-processing pass (two triangles, millions of fragments) and the vertex units twiddled their thumbs. Whatever the frame needed, half the machine was the wrong half.

The unified shader architecture (Xbox 360's Xenos in 2005, NVIDIA's G80 in 2006) replaced both with one pool of general-purpose cores that runs vertex work and fragment work — the hardware scheduler simply hands whichever warps are ready to whichever SMs are free. The pool load-balances itself, minute by minute, frame phase by frame phase. And the historic side-effect: once the shader cores were general enough to run either kind of shader, they were general enough to run anything — CUDA arrived within months, and the GPU-compute world of the previous module exists because graphics needed better load balancing.

Why fixed-function survives: the specialisation argument

If unifying the shaders was such a win, why not go all the way — make everything a program? Because for the remaining stages, dedicated silicon wins by margins too large to ignore. A hardwired rasterizer, texture filter or blender does its one job at roughly 10–100× better energy- and area-efficiency than the same job written as shader code. The reasons stack up:

So the modern GPU is a treaty line: stages whose algorithms artists and engine programmers need to change went programmable; stages whose arithmetic is settled stayed circuits. Both sides of the treaty are on the die because each is the cheapest way to do its half of the work.

The plumbing: who feeds the pool?

One pool of SMs raises a distribution problem: a triangle is rasterized by one raster engine, but its fragments may be millions — far too many for the SMs next to that rasterizer. The solution is screen-space tiling: the screen is divided into small tiles, and each tile is permanently owned by one raster-engine-plus-SM-cluster. A big triangle is chopped along tile boundaries and its pieces stream to their owners in parallel, so fragment work spreads evenly across the whole pool no matter how lopsided the geometry is. (Keep this trick in mind — the final lesson of this module shows a whole GPU family built around tiles far more radically.)

Less than you might guess — and more than the marketing suggests. On a modern gaming GPU the SM pool (with its register files and caches) dominates the area; the raster engines, texture units and ROPs are a modest fraction of the die. But judge them by work done per joule and the picture inverts: during a busy frame those small blocks perform arithmetic that, written as shader code, would swamp the entire SM pool. A texture unit's trilinear filter is ~30 shader instructions replaced by one hardwired pipeline; a blender's read–modify–write would be an un-parallelisable mess in software. Fixed-function silicon is small precisely because it is efficient — the 100× advantage means a sliver of die does an SM-pool's worth of work. That trade — a little permanent silicon for a huge recurring saving — is the economics of every accelerator ever built, from video decoders to AI matrix engines.

The stage list reads like a sequence — first vertices, then raster, then shading — and beginners reason about frames that way: "the GPU is in its rasterization phase now." No. The logical pipeline is an abstraction about the order one triangle's data flows, not about what the chip does at any instant. In the hardware, thousands of triangles are in flight at once, in every stage simultaneously: while one triangle's fragments are being blended, another's are being shaded, another is being rasterized, and ten thousand vertices behind them are being transformed. Every stage of the silicon is busy all the time — that is the whole design goal. Treating stages as per-frame phases misreads all performance behaviour: a "vertex-bound" frame does not wait in a vertex stage; it means the SM pool's vertex warps are the bottleneck that everything else drains faster than. Profile pipelines like factories (find the slowest station), never like recipes (sum the steps).