↑

Case studies

zdxc X Hyperion

Glide, 2,688 shader assets, DXIL and SPIR-V

HyperionEngine compiles its shaders through IDxcCompiler3: a -P preprocess call, then the compile with -HV 2021 -O3. The game is Glide. Swapping DXC's library for zdxc's is the only change.

Compiling the cook's 8,770 recorded compile calls, 24 threads
DXC358 shaders/s
zdxc drop-in7,830 shaders/s21.9×
zdxc --job3,373 shaders/s9.4×
Windows, DXIL. Ryzen 9 7900 (24 threads). Through each compiler's dxcompiler.dll in one process, and as one zdxc --job batch, which also reads every source and writes every object (median of 3). DXC 1.8.2505 against zdxc ddefd45. Higher is better

Before and after

The same frame of Glide, with its shaders compiled by DXC and by zdxc.

Glide's title screen over a desert canyon, zdxc
Glide's title screen over a desert canyon, DXC
DXCzdxc
Drag to compare: DXC on the left, zdxc on the right.
Glide's title screen over a desert canyon, DXC
DXC
Glide's title screen over a desert canyon, zdxc
zdxc

Results

DXC zdxc
Cook, wall time 59.3 s 23.3 s 2.5×
Compile call, median 12.6 ms 0.91 ms 13.9×
Compile call, 99th percentile 129 ms 11 ms 11.6×
Slowest compile 3.2 s 131 ms 24×
DXIL output 76.4 MB 53.7 MB
  • All shaders built with both DXC and zdxc.
  • Valid output. All 8,770 objects pass DXC's validator.
  • Same picture. Glide renders the same frame with either compiler (captured with zdxc 2526fa6).
  • macOS, SPIR-V. On an Apple M5, the Vulkan cook takes 10–11 s with zdxc against 30–32 s with DXC, and every SPIR-V module passes spirv-val.

How it was measured

The engine's BlobStorageCookCommandlet cooks Glide from an empty shader cache, three times with each compiler, interleaved. A shim library in front of the real one times every Compile call and records it; the recording is then replayed through each compiler in one process, on one thread and on 24.

zdxc X Unreal Engine

UE 5.8.4 editor, 11,156 startup shaders, DXIL with work graphs

Unreal Engine 5.8.4, built from source, opens the StarterContent sample's StarterMap with an empty shader cache. Its ShaderCompileWorker processes load DXC's dxcompiler.dll from Engine/Binaries/ThirdParty/ShaderConductor/Win64. Replacing that one file with zdxc's drop in libraries is the only change: D3D12, Shader Model 6.6, work graphs on.

Try it yourself: set up zdxc with Unreal Engine, using pre-release binaries or compiling from source.

Compiling the startup's 11,488 recorded compile calls, 24 threads
DXC37 shaders/s
zdxc drop-in149 shaders/s4.0×
zdxc --job397 shaders/s10.6×
Windows, DXIL. Ryzen 9 7900 (24 threads). Through each compiler's dxcompiler.dll on 24 processes, as the editor's workers call it, and as one zdxc --job batch on 24 threads (median of 3). Unreal's DXC 1.8 against zdxc eeb5a3f. Higher is better

Startup, side by side

Unreal's DXC 1.8 (2:56.0) against zdxc eeb5a3f (0:45.5), real time.

Before and after

StarterMap in the editor, its shaders compiled by DXC and by zdxc.

StarterMap's two-storey timber house on floating tiles, under a blue sky, zdxc
StarterMap's two-storey timber house on floating tiles, under a blue sky, DXC
DXCzdxc
Drag to compare: DXC on the left, zdxc on the right.
StarterMap's two-storey timber house on floating tiles, under a blue sky, DXC
DXC
StarterMap's two-storey timber house on floating tiles, under a blue sky, zdxc
zdxc

Results

DXC zdxc
Editor startup, compiles in flight 193 s 45 s 4.3×
Editor startup, worker thread time 2,193 s 400 s 5.5×
Compile call, median 154 ms 23 ms 6.8×
Compile call, 99th percentile 2.3 s 0.49 s 4.7×
Slowest compile 6.0 s 2.1 s 2.8×
Shader code the editor keeps 178 MiB 193 MiB
  • Valid output. Every object zdxc writes passes Unreal's own DXIL validator (dxil.dll 1.8).
  • Same picture. The editor opens the map and renders it with no D3D12 debug-layer errors with either compiler.
  • Code size. zdxc's DXIL is 1.09 times DXC's over the whole recording. The driver turns it into pipelines a little more slowly. It's likely DXC produces dxil which is more amenable to isa lowering on end user machines.