r.ShaderCodeLibrary.MaxShaderGroupSize

r.ShaderCodeLibrary.MaxShaderGroupSize

#Overview

name: r.ShaderCodeLibrary.MaxShaderGroupSize

This variable is created as a Console Variable (cvar).

It is referenced in 3 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.ShaderCodeLibrary.MaxShaderGroupSize is to control the maximum uncompressed size of a group of shaders that can be compressed or decompressed together in the Unreal Engine’s shader code library system.

This setting variable is primarily used in the RenderCore module of Unreal Engine, specifically within the shader code archive functionality. It’s an important part of the engine’s shader management and optimization system.

The value of this variable is set through an FAutoConsoleVariableRef named CVarShaderCodeLibraryMaxShaderGroupSize. It’s initialized with a default value of 1,024,000 bytes (1MB), which is noted to take about 0.1ms to decompress on a high-end PC.

This variable interacts closely with the shader grouping and compression systems. It’s used to determine how shaders are grouped together for compression and decompression, which can have significant performance implications.

Developers should be aware that:

  1. This variable affects shader loading times and memory usage.
  2. If a group of shaders exceeds this size limit, it will be split into subgroups.
  3. In cases where a single shader exceeds the limit, the limit will be ignored to prevent shader loss.

Best practices when using this variable include:

  1. Monitoring performance impacts when adjusting this value.
  2. Considering hardware capabilities of target platforms when setting this value.
  3. Balancing between load time (smaller groups) and compression efficiency (larger groups).
  4. Avoiding frequent changes to this value, as it’s marked as read-only and render thread safe.

It’s important to note that this variable is crucial for optimizing shader loading and processing, especially on platforms with limited resources or when dealing with large numbers of shaders.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/ShaderCodeArchive.cpp:60

Scope: file

Source code excerpt:

int32 GShaderCodeLibraryMaxShaderGroupSize = 1024 * 1024;	// decompressing 1MB of shaders takes about 0.1ms on PC (TR 3970x, Oodle Mermaid6).
static FAutoConsoleVariableRef CVarShaderCodeLibraryMaxShaderGroupSize(
	TEXT("r.ShaderCodeLibrary.MaxShaderGroupSize"),
	GShaderCodeLibraryMaxShaderGroupSize,
	TEXT("Max (uncompressed) size of a group of shaders to be compressed/decompressed together.")
	TEXT("If a group exceeds it, it will be evenly split into subgroups which strive to not exceed it. However, if a shader group is down to one shader and still exceeds the limit, the limit will be ignored."),
	ECVF_RenderThreadSafe | ECVF_ReadOnly
);

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/ShaderCodeArchive.cpp:1390

Scope (from outer to inner):

file
function     void FIoStoreShaderCodeArchive::CreateIoStoreShaderCodeArchiveHeader

Source code excerpt:

	// We group the shaders by those sets of shadermaps - all shaders referenced by the same shadermap(s) are a candidate for being a single group. Then we potentially split this candidate group
	// into raytracing and non-raytracing groups (so we can avoid preloading RTX shaders run-time if RTX is disabled), and then each of those is potentially split further by size
	// (to avoid too large groups that will take too much time to decompress - this is regulated by r.ShaderCodeLibrary.MaxShaderGroupSize). The results of that process (note, it can still be
	// a single group) is added to the header.
	// Each group's indices, like in case of shadermaps, are stored in ShaderIndices array. Before we append a new group's indices however, we look if we can find an existing range that we can reuse.
	const bool bSeparateRaytracingShaders = (Format == FName("PCD3D_SM5"));

	TArray<TPair<uint32, TArray<int32>>> ShaderToShadermapsArray;
	{

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/ShaderCodeArchive.cpp:1543

Scope (from outer to inner):

file
function     void FIoStoreShaderCodeArchive::CreateIoStoreShaderCodeArchiveHeader

Source code excerpt:

	};

	/** Second stage of processing shader group. Here we potentially split the group into smaller ones (as equally as possible), striving to meet limit imposed by r.ShaderCodeLibrary.MaxShaderGroupSize */
	auto ProcessShaderGroup_SplitBySize = [&OutHeader, &SerializedShaders, &ProcessShaderGroup_AddNewGroup, &MaxUncompressedShaderGroupSize](TArray<uint32>& CurrentShaderGroup)
	{
		// calculate current group size
		uint32 GroupSize = 0;
		for (uint32 ShaderIdx : CurrentShaderGroup)
		{