Vertex Shaders and Pixel Shaders

Vertex Shader Processing

In DX8, the vertex pipeline has been made entirely programmable. Arbitrary vertex data is processed in an arbitrary way using the vertex shader, which then places the output values into the write-only output registers.

The shader vertex processor.

As you can see, this diagram is considerably cleaner than the diagram for the fixed-function vertex pipeline, and, as a basic flow diagram, there's little missing.

oPos is the 'screenspace' position of the vertex, oD0 is the diffuse color, oD1 is the specular color, oT0 up to oT3 are four pairs of texture coordinates. oFog is the range of the fog, allowing for a certain amount of flexibility, but not as much as some people would have wanted. oPts is the point size for the point sprite processor. Don't worry about that one, point sprite processing is one of those things for the effects programmer to worry about.

FF Pixel Processing

The fixed-function pixel processing pipeline is, frankly, a bit of a mess. Commonly referred to as the texture cascade, once you start to look into how it works, you realize that this bit of architecture has probably outlived its usefulness.

The basic model is fairly simple to grasp. Each stage in the cascade computes a color and an alpha value, and passes these on to the next stage in the cascade. Once all of the stages have been computed, the pixel value is then passed to the frame buffer blending unit. Each stage has a color operation, typically with 2 arguments (although two triadic operations have been added for DX8), and an alpha operation, which is effectively another color operation that operates with scalar values.

The first weird and wonderful thing is that not all of these operations are supported on all hardware, so for each type of operation you want to use, you have to check that the hardware can support it. Most of this information can be extracted from the capabilities of the graphics card, however, more complicated issues are no longer handled by capabilities. For example, a certain cascade may work fine for 2D textures, but the processing will not work if the texture is a cube map.

To resolve these awkward compatibility cases, a function called 'ValidateDevice' was added to the API. Using this method, you set up the type of drawing you'd like to carry out, and then call 'ValidateDevice.' If the call fails, then you set up a simpler method and try again.

Unfortunately, 'ValidateDevice' is a fairly new thing, so older drivers will try to emulate 'ValidateDdevice's' functionality, generally extremely poorly. So as well as 'ValidateDevice,' you'll also want to check the capabilities of the graphics card. But, be aware that some old drivers will lie about their capabilities as well.

Hopefully that's confused you, because it confuses everybody else. To summarize, something had to be done.