Expand description
A draw on the CPU, as Direct3D draws an indexed triangle list: the vertex program for each vertex, each triangle clipped, mapped through the viewport and rasterized, the pixel program for each pixel it covers, the depth test, and the render targets written. It is for re-running a draw recorded from a running game on the programs the record names, so its pixels can be set against the ones the game wrote.
The rules are the Direct3D 11 functional specification’s (which Direct3D 12 keeps), held to Microsoft’s WARP
rasterizer by the exec_warp_draw tests:
- Linking. A pixel program input reads the vertex program output of the same semantic and index (names compared
without case), component by component;
SV_Positionis the pixel’s position,SV_IsFrontFacethe triangle’s facing. An input no output carries is an error. - Clipping. A triangle is clipped to
0 <= z <= w(depth clipping) and to-w <= x <= w,-w <= y <= w: the viewport, section 15.4 of the D3D11.3 specification’s clip volume. 15.4 allows a guard band (“or arbitrarily wider range if implementation uses a guard band”); WARP uses none (a triangle cut 16.25 pixels past the viewport instead of at it puts the pixels it draws up to 1e-4 off WARP’s), so a vertex clipping makes on a side of the viewport is snapped like any other. A vertex near the camera plane, whose screen position is far outside, is snapped only after clipping brings it in. Those planes leave every vertexw >= |x|, |y|, z >= 0, so a division bywis finite but at the clip-space origin, which a clipped polygon reaches only when its triangle’s vertices are linearly dependent: its plane holds the camera and it has no area on screen, so it draws nothing. A vertex clipping makes holds its weights on the triangle’s three vertices in clip space, and its outputs are the triangle’s by the interpolation of the input they feed: perspective-correct ones by those weights, the screen-linear ones (noperspective) by the weights of its screen position (a clip-space weight times the vertex’s w, normalised), and flat ones the provoking vertex’s. A triangle with a NaN position after clipping draws nothing (15.4); one with an infinity becomes NaN where clipping cuts it, which 15.4 allows (“may or may not result in a discarded primitive”). - Viewport.
x = X + (x/w + 1) / 2 * W,y = Y + (1 - y/w) / 2 * H(y down),z = MinDepth + z/w * (MaxDepth - MinDepth). - Rasterization. Positions are snapped to 1/256 of a pixel (16.8 fixed point), as D3D’s 8 bits of sub-pixel precision (15.16), to the nearest with a tie to even and saturating at the format’s range (3.2.4.1). A pixel is drawn when its centre is inside the triangle, or on an edge that is a top or a left edge. The facing is the sign of the snapped area: with y down a clockwise triangle is front facing unless the state says counter-clockwise; culling drops the facing it names; a zero-area triangle draws nothing.
- Interpolation. At the pixel centre, from the snapped positions: perspective-correct (the default), linear in
screen space (
noperspective) or the provoking vertex’s value (nointerpolation, integers; the triangle’s first vertex). Centroid and sample interpolation are the centre’s (one sample a pixel). Depth is linear in screen space and clamped to the viewport’s depth range. - Pixels. In 2 x 2 quads aligned to even pixels, uncovered lanes run as helpers (their inputs extrapolated) so derivatives and implicit levels of detail are the quad’s; a helper writes nothing. A discarded pixel writes nothing. The depth test runs after the pixel program (its result is the same: a pixel that fails writes nothing); a pixel that passes writes every target lane the program writes and, when the state writes depth, its depth. Triangles are drawn in index order, so a later one overwrites an earlier one where both pass.
Structs§
- Depth
State - The depth test and whether a pixel that passes writes its depth.
- Draw
Shader - A vertex and a pixel program linked for drawing.
- Draw
Stats - What a draw did.
- Rasterizer
- The fixed-function state of a draw.
- Surface
- What a draw writes to: render targets by output register (
width * heighttexels each, row by row, as the pixel program’s output words) and the depth buffer. - Viewport
- The viewport: where clip space lands in the targets.