A shader does not arrive on disk in a form the GPU can execute. It arrives as bytecode — SPIR-V under Vulkan, DXBC or DXIL under Direct3D — and the driver must compile that into hardware machine code before the GPU will touch it. That compilation is the source of shader compilation stutter: the first time a pipeline state is encountered, the work happens synchronously, and the frame waits.

The cache exists to make that work happen once.

Layers in the compilation chain

FROM THIS ENTRY
Bytecode (SPIR-V, DXBC, DXIL)what ships on disk; GPU cannot execute it directly
Layer cache (e.g. .dxvk-cache)translated pipeline state objects, at the compatibility layer
Driver cache (~/.cache/vendor/…)hardware machine code, produced by the driver
These are distinct stages; both caches may exist simultaneously for the same shader

What the cache holds and where it lives

After the driver compiles a shader, most graphics stacks write the result to disk. On Linux the default location is typically inside ~/.cache, under a vendor-specific subdirectory — AMD, Intel and NVIDIA each manage their own. A compatibility layer running between the application and the driver can maintain a second cache at its own layer, storing translations of the original bytecode before the driver even sees them. Wine's DXVK component, for example, keeps a .dxvk-cache file alongside the game executable; that file holds compiled Vulkan pipeline state objects, not raw shader source, so the driver's subsequent job is shorter.

Two distinct caches therefore often exist simultaneously: the layer's own, and the driver's. They are not duplicates — they operate on different representations at different points in the compilation chain.

A graphics card backplate and connectors in macro
FIG. 2The card the shaders are finally compiled for — whichever hardware the program believed in.

What invalidates a cache entry

A cache entry is keyed on a combination of the shader bytecode itself and the pipeline state object that accompanies it — blend mode, render target format, vertex layout. Change any of those, and the key no longer matches. The entry is useless.

Driver updates invalidate everything. When the driver version changes, the hardware machine code it would produce also changes, so cached output from the previous version is not trusted. The entire cache is discarded and rebuilt during the next session. This is why a driver update reliably causes stutter on first launch: you are paying the compilation cost again for every pipeline the program will exercise.

The layer's own cache is invalidated more selectively. DXVK, for instance, embeds a cache version number; when the layer itself updates in a way that affects translation output, it bumps that number and discards prior entries. The driver cache underneath reacts to its own version independently.

Corruption also invalidates entries, and cache files are not immune. A partial write during a crash leaves a file the reader cannot parse; most implementations fall back to recompilation rather than failing outright.

The practical implication is simple: the cache speeds up every run after the first, but that first run on a new driver — or after a layer update — is always a cold start.

What kills a cache

FROM THIS ENTRY
Different pipeline state (blend mode, render target format, vertex layout)key no longer matches
Driver version updateall driver-cache entries discarded, full cold recompile on next run
Layer version updatelayer's own cache version bumped, prior entries dropped
File corruption from a crashentry unreadable, falls back to recompilation
A monitor showing a flat test pattern in a dim room
FIG. 3A flat test pattern holds every variable still except the one being measured.

Shimwork is an independent publication about compatibility layer internals. We are not a software vendor, distributor or support service.

FILED UNDER: PIPELINESHORT ENTRY