r.ShaderPipelineCache.SaveAfterPSOsLogged
r.ShaderPipelineCache.SaveAfterPSOsLogged
#Overview
name: r.ShaderPipelineCache.SaveAfterPSOsLogged
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Set the number of PipelineStateObjects to log before automatically saving. 0 will disable automatic saving (which is the default now, as automatic saving is found to be broken).
It is referenced in 4
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.ShaderPipelineCache.SaveAfterPSOsLogged is to control the automatic saving behavior of the Shader Pipeline Cache in Unreal Engine 5. It sets the number of Pipeline State Objects (PSOs) to log before automatically saving the cache.
This setting variable is primarily used by the Rendering system, specifically the Shader Pipeline Cache subsystem. It’s part of the RenderCore module, as evidenced by its location in the ShaderPipelineCache.cpp and ShaderPipelineCache.h files.
The value of this variable is set through the console variable system in Unreal Engine. It’s defined as a TAutoConsoleVariable with a default value of 0, which disables automatic saving.
This variable interacts closely with the FShaderPipelineCache class and the FPipelineFileCacheManager. It’s used in the ReadyForAutoSave function to determine when to trigger an automatic save of the pipeline cache.
Developers should be aware that:
- Setting this value to 0 disables automatic saving.
- The current default (0) is set because automatic saving was found to be broken at some point.
- This variable affects performance and disk I/O, as it triggers saves of potentially large cache files.
Best practices when using this variable include:
- Only enable automatic saving (by setting a non-zero value) if you’re actively developing and need frequent cache updates.
- Choose a value that balances between saving frequently enough to capture new PSOs and not so frequently that it impacts performance.
- Consider your game’s PSO generation rate when setting this value.
Regarding the associated variable CVarPSOFileCacheSaveAfterPSOsLogged:
This is the actual console variable object that stores and manages the r.ShaderPipelineCache.SaveAfterPSOsLogged setting. It’s defined as a static TAutoConsoleVariable
The purpose of this variable is the same as r.ShaderPipelineCache.SaveAfterPSOsLogged - it’s the underlying implementation of the setting.
It’s used directly in the FShaderPipelineCache::ReadyForAutoSave function to determine if an auto-save should occur based on the number of PSOs logged.
Developers should be aware that modifying this variable directly (rather than through the console command system) could lead to unexpected behavior.
Best practices for this variable are the same as for r.ShaderPipelineCache.SaveAfterPSOsLogged, as they represent the same setting.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/ShaderPipelineCache.cpp:94
Scope: file
Source code excerpt:
);
static TAutoConsoleVariable<int32> CVarPSOFileCacheSaveAfterPSOsLogged(
TEXT("r.ShaderPipelineCache.SaveAfterPSOsLogged"),
0,
TEXT("Set the number of PipelineStateObjects to log before automatically saving. 0 will disable automatic saving (which is the default now, as automatic saving is found to be broken)."),
ECVF_Default | ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarPSOFileCacheAutoSaveTime(
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Public/ShaderPipelineCache.h:57
Scope: file
Source code excerpt:
* - PSOs are logged as they are encountered as the Unreal Engine does not provide facility to cook them offline, so this system will only collect PSOs which are actually used to render.
* - As such you must either manually play through the game to collect logs or automate the process which is beyond the scope of this code.
* - The data can be saved at any time by calling FShaderPipelineCache::SavePipelineFileCache and this can happen automatically after a given number of PSOs by setting r.ShaderPipelineCache.SaveAfterPSOsLogged = X where X is the desired number of PSOs to log before saving (0 will disable auto-save).
* - Log files are shader platform specific to reduce overheads.
*
* Notes:
* - The open cache file can be changed by closing the existing file with ClosePipelineFileCache (which implicitly Fast saves) and then opening a new one with OpenPipelineFileCache.
* - Different files can be used to minimise PSO compilation by having a file per-scalability bucket (i.e. one file for Low, one for Med, one for High).
* - When logging if you switch files only new entries from after the switch will be logged, which means you will miss any PSOs that should have been logged prior to switching. This prevents polluting the cache with unexpected entries.
* - The UnrealEd.MergeShaderPipelineCaches command-let can be used to merge cache files with the same file-version, shader platform and game-version.
*
* File Locations & Packaging:
* - The writable cache file is always stored in the User Saved directory.
* - The game can also provide an immutable copy within its Game Content directory which will be used as the initial or seed data.
* - Having generated logs in development and merged them with UnrealEd.MergeShaderPipelineCaches they should be packaged inside the Gane Content directory for the relevant platform.
*
* Requirements:
* - FShaderCodeLibrary must be enabled via Project Settings > Packaging > "Share Material Shader Code".
* - Enabling "Native Shader Libraries" is optional, but strongly preferred for Metal.
*/
class FShaderPipelineCache : public FTickableObjectRenderThread
{
// the FShaderPipelineCacheTask class represents a pipeline precompile of a single PSO file cache.
friend class FShaderPipelineCacheTask;
public:
/**
* Initializes the shader pipeline cache for the desired platform, called by the engine.
* The shader platform is used only to load the initial pipeline cache and can be changed by closing & reopening the cache if necessary.
*/
static RENDERCORE_API void Initialize(EShaderPlatform Platform);
/** Terminates the shader pipeline cache, called by the engine. */
static RENDERCORE_API void Shutdown();
/** Pauses precompilation. */
static RENDERCORE_API void PauseBatching();
enum class BatchMode
{
Background, // The maximum batch size is defined by r.ShaderPipelineCache.BackgroundBatchSize
Fast, // The maximum batch size is defined by r.ShaderPipelineCache.BatchSize
Precompile // The maximum batch size is defined by r.ShaderPipelineCache.PrecompileBatchSize
};
/** Sets the precompilation batching mode. */
static RENDERCORE_API void SetBatchMode(BatchMode Mode);
/** Resumes precompilation batching. */
static RENDERCORE_API void ResumeBatching();
/** true if pipeline cache(s) are precompiling. */
static RENDERCORE_API bool IsPrecompiling();
/** Returns the number of pipelines waiting for precompilation of the current PSOFC task.
if there are multiple PSOFCs pending this will return a minimum value of 1. It may increase as subsequent caches are processed.*/
static RENDERCORE_API uint32 NumPrecompilesRemaining();
/** Opens the shader pipeline cache file with either the LastOpened setting if available, or the project name otherwise */
#Associated Variable and Callsites
This variable is associated with another variable named CVarPSOFileCacheSaveAfterPSOsLogged
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/ShaderPipelineCache.cpp:93
Scope: file
Source code excerpt:
ECVF_Default | ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarPSOFileCacheSaveAfterPSOsLogged(
TEXT("r.ShaderPipelineCache.SaveAfterPSOsLogged"),
0,
TEXT("Set the number of PipelineStateObjects to log before automatically saving. 0 will disable automatic saving (which is the default now, as automatic saving is found to be broken)."),
ECVF_Default | ECVF_RenderThreadSafe
);
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/ShaderPipelineCache.cpp:1607
Scope (from outer to inner):
file
function bool FShaderPipelineCache::ReadyForAutoSave
Source code excerpt:
{
bool bAutoSave = false;
uint32 SaveAfterNum = CVarPSOFileCacheSaveAfterPSOsLogged.GetValueOnAnyThread();
uint32 NumLogged = FPipelineFileCacheManager::NumPSOsLogged();
const double TimeSinceSave = FPlatformTime::Seconds() - LastAutoSaveTime;
// autosave if its enabled, and we have more than the desired number, or it's been a while since our last save
if (SaveAfterNum > 0 &&