FShaderCache

Overview

The FShaderCache provides mechanisms for reducing shader hitching in-game. It supports the OpenGLDrv RHI, and works on Mac, Linux, and Windows platforms.

There are a number of console commands that can be used to enable or disable FShaderCache functionality.

Console Command Description
r.UseShaderCaching [0/1]
  • Early submission during shader deserialisation rather than on-demand.

  • Tracking of bound-shader-states so that they may be pre-bound during early submission.

r.UseShaderDrawLog [0/1] Tracking of RHI draw states so that each bound-shader-state can be predrawn.
r.UseShaderPredraw [0/1] Predrawing of tracked RHI draw states to eliminate first-use hitches.
r.PredrawBatchTime [Time in (ms)] Control over time spent predrawing each frame to distribute over many frames if required. Use -1 for all.

Use

The cache should be populated by enabling r.UseShaderCaching and r.UseShaderDrawLog on a development machine. Users/players should then consume the cache by enabling r.UseShaderCaching and r.UseShaderPredraw. Draw logging (r.UseShaderDrawLog) adds noticeable fixed overhead so avoid enabling it in shipped products if possible. Since the caching is done via shader hashes, it is also advisable to only use this as a final optimization tool when content is largely complete as changes to shader hashes will result in unused entries accumulating in the cache, increasing cache size without reducing hitches.

The code will first try and load the writable cache, then fall back to the distribution cache if needed.

Cache Type Cache Location
Writable <Game>/Saved/ShaderCache.ushadercache
Distribution <Game>/Content/ShaderCache.ushadercache

Handling Updates/Invalidation

When the cache needs to be updated and writable caches invalidated the game should specify a new GameVersion. Call FShaderCache::SetGameVersion before initializing the RHI (which initializes the cache). This will cause the contents of a cache generated by a previous version to be ignored. At present you cannot carry over cache entries from a previous version.

Region/Stream Batching

For streaming games, or where the cache becomes very large, calls to FShaderCache::SetStreamingKey should be added with unique values for the currently relevant game regions/streaming levels (as required). Logged draw states will be linked to the active streaming key. This limits predrawing to only those draw states required by the active streaming key on subsequent runs.