Predication is a feature that enables the GPU rather than the CPU to determine to not draw, copy, or dispatch an object.
The typical use of predication is with occlusion; if a bounding box is drawn and is occluded, there is obviously no point in drawing the object itself. In this situation, the drawing of the object can be "predicated", enabling its removal from actual rendering by the GPU.
At first, this might seem redudant over and above the standard depth test plus an early depth pass. But predication can remove the overhead of the draw command state itself, plus the rasterization. While an early depth pass removes unnecessary pixels, it can still execute vertex, hull, domain, and geometry shaders, and invoke the fixed-function input assembler, tesselator, and rasterizer. By drawing a simple bounding box or similar bounding volume—which is simpler to process and rasterize than the real model—you avoid unnecessary rasterization and processing.
Unlike Direct3D 11, predication is decoupled from queries, and is expanded in Direct3D 12 to enable an application to predicate objects based on any reasoning the app developer may decide on (not just occlusion).
Predication can be set based on the value of 64-bits within a buffer (refer to D3D12_PREDICATION_OP).
When the GPU executes a SetPredication command it snaps the value in the buffer. Future changes to the data in the buffer do not retroactively affect the predication state.
If the input parameter Buffer is NULL, then predication is disabled.
Predication hints are not present in the Direct3D 12 API; and predication is allowed on direct, compute, and copy command lists. The source buffer can be in any heap type (default, upload, readback, custom).
The core runtime will validate the following:
- AlignedBufferOffset is a multiple of 8 bytes
- The resource is a buffer
- The operation is a valid member of the enumeration
- SetPredication cannot be called from within a bundle
- The command list type supports predication
- The offset does not exceed the buffer size
The set of operations which can be predicated are:
ExecuteBundle is not predicated itself. Instead, individual operations from the list above which are contained in side of the bundle are predicated.