DirectX Pipeline Statistics: Diagnosing Bottlenecks
DirectX pipeline statistics queries provide granular, hardware-level invocation and primitive metrics across the rendering pipeline, allowing graphics engineers to pinpoint performance bottlenecks such as vertex processing overhead, excessive overdraw, and geometry rejection. By capturing quantitative data directly from the GPU during execution, these queries reveal exactly where the rendering workload stalls. This article details the primary metrics recorded by pipeline statistics in DirectX and explains how developers interpret them to identify and resolve GPU pipeline inefficiencies.
Core Metrics Captured by Pipeline Statistics
In both DirectX 11 and DirectX 12
(D3D12_QUERY_DATA_PIPELINE_STATISTICS), pipeline statistics
queries capture execution counts at each major stage of the rendering
pipeline:
- Input Assembler (IA):
IAVerticesandIAPrimitivesrecord the total raw geometry fed into the pipeline. - Vertex Shader (VS):
VSInvocationstracks how many times the vertex shader executed. - Hull & Domain Shaders (HS/DS):
HSInvocationsandDSInvocationstrack tessellation operations. - Geometry Shader (GS):
GSInvocationsandGSPrimitivesmeasure geometry expansion or stream-out workloads. - Clipper (C):
CInvocationsreflects primitives that reached the clipping stage, whileCPrimitivescounts primitives that survived clipping and proceeded downstream. - Pixel Shader (PS):
PSInvocationsmeasures the total number of fragments shaded. - Compute Shader (CS):
CSInvocationstracks compute thread group dispatches.
Identifying Geometry and Culling Bottlenecks
One of the most effective uses of pipeline statistics is detecting inefficient geometry handling:
- Ineffective Frustum and Back-Face Culling: If the
ratio of
CInvocationstoCPrimitivesis exceptionally high, the GPU is spending excessive cycles processing geometry that is ultimately clipped or discarded outside the viewport. Developers resolve this by implementing coarse CPU frustum culling, GPU-driven occlusion culling (e.g., via compute shaders), or mesh clustering. - Sub-Pixel and Dense Geometry Overhead: A high count
of
IAPrimitivesrelative to a low number of resulting pixels shaded often points to over-tessellated meshes or distant objects lacking appropriate Level of Detail (LOD). This indicates that the vertex pipeline is saturated with micro-triangles that yield little visual impact, necessitating more aggressive LOD transitions. - Vertex Cache Misses: Comparing
IAVerticestoVSInvocationshelps evaluate post-transform cache efficiency. IfVSInvocationssignificantly exceeds expected unique vertex counts, the index buffers may not be optimized for spatial locality.
Pinpointing Pixel Shader and Fill-Rate Limitations
The PSInvocations counter reveals the computational load
imposed on fragment processing:
- Overdraw Detection: By dividing
PSInvocationsby the target render resolution, developers determine the average overdraw factor per frame or per draw call. An elevated ratio in forward renderers indicates that overlapping geometry is being shaded repeatedly. This prompts solutions like front-to-back sorting, Depth Pre-Passes, or transitioning to deferred rendering paths. - Early-Z Rejection Failures: If
PSInvocationsmatches the total rendered triangle surface area despite occluders being present, the pipeline may have disabled hardware Early-Z optimizations. This commonly happens when shaders write to depth (SV_Depth), use discard/clip instructions, or activate specific blend modes, forcing the engine to fall back to late fragment testing.
Analyzing Shader Expansion Inefficiencies
Pipeline statistics expose the hidden performance costs of programmable stages that dynamically amplify geometry:
- Geometry Shader Sinks: When
GSPrimitivesis vastly higher thanGSInvocations, the geometry shader may be generating heavy amplification that saturates GPU ring buffers and stalls the rasterizer. - Tessellation Balancing: Comparing
HSInvocationsandDSInvocationsensures tessellation factors are configured correctly. A high domain shader invocation count relative to visual fidelity signals over-tessellation, which can be mitigated by adjusting tessellation factors dynamically based on camera distance.
Practical Diagnostic Implementation
Developers typically wrap critical render passes, draw call batches,
or individual debug profiles inside BeginQuery and
EndQuery blocks. When paired with timestamp queries,
pipeline statistics correlate stage-by-stage counts directly with GPU
execution time.
By analyzing these hardware metrics inside in-engine profilers or diagnostic tools, developers can immediately determine whether an underperforming pass is bounded by geometry throughput, rasterization, or fragment shading, avoiding guesswork during engine optimization.