bAllowAsynchronousShaderCompiling

bAllowAsynchronousShaderCompiling

#Overview

name: bAllowAsynchronousShaderCompiling

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 9 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of bAllowAsynchronousShaderCompiling is to control whether shaders can be compiled asynchronously in the background or if the compilation process should block after each material.

This setting variable is primarily used by the shader compiling system within Unreal Engine 5. Based on the provided code snippets, it’s clear that this variable affects the behavior of the FShaderCompilingManager class, which is responsible for managing shader compilation tasks.

The value of this variable is set in the engine’s configuration file (GEngineIni) under the “DevOptions.Shaders” section. It can be retrieved and modified through the engine’s configuration system.

This variable interacts closely with other shader compilation-related variables, such as bAllowCompilingThroughWorkers and MaxShaderJobBatchSize. It’s also affected by the platform’s multithreading capabilities.

Developers should be aware of the following:

  1. If the platform doesn’t support multithreading, bAllowAsynchronousShaderCompiling is automatically set to false.
  2. This setting significantly affects the shader compilation workflow. When set to true, it allows for background compilation, which can improve overall engine performance but may lead to temporary visual artifacts while shaders are being compiled.
  3. When set to false, shader compilation will block the main thread, ensuring all shaders are ready before proceeding but potentially causing noticeable hitches or longer loading times.

Best practices when using this variable include:

  1. Enable it for development and testing to improve iteration times.
  2. Consider disabling it for final builds or when debugging specific shader-related issues.
  3. Always test the game thoroughly with both settings to ensure smooth performance and visual consistency in all scenarios.
  4. Be aware of the trade-offs between background compilation (faster overall, potential temporary artifacts) and synchronous compilation (slower, but guaranteed complete shaders).

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:1950, section: [DevOptions.Shaders]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompiler.cpp:3480

Scope (from outer to inner):

file
function     void FShaderCompileThreadRunnableBase::StartThread

Source code excerpt:

void FShaderCompileThreadRunnableBase::StartThread()
{
	if (Manager->bAllowAsynchronousShaderCompiling && !FPlatformProperties::RequiresCookedData())
	{
		Thread = FRunnableThread::Create(this, GetThreadName(), 0, TPri_Normal, FPlatformAffinity::GetPoolThreadMask());
	}
}

FShaderCompileThreadRunnable::FShaderCompileThreadRunnable(FShaderCompilingManager* InManager)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompiler.cpp:3577

Scope (from outer to inner):

file
function     uint32 FShaderCompileThreadRunnableBase::Run

Source code excerpt:

{
	LLM_SCOPE_BYTAG(ShaderCompiler);
	check(Manager->bAllowAsynchronousShaderCompiling);
	while (!bForceFinish)
	{
		CompilingLoop();
	}
	UE_LOG(LogShaderCompilers, Display, TEXT("Shaders left to compile 0"));

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompiler.cpp:4392

Scope (from outer to inner):

file
function     int32 FShaderCompileThreadRunnable::CompilingLoop

Source code excerpt:

		const int32 NumActiveThreads = PullTasksFromQueue();

		if (NumActiveThreads == 0 && Manager->bAllowAsynchronousShaderCompiling)
		{
			// Yield while there's nothing to do
			// Note: sleep-looping is bad threading practice, wait on an event instead!
			// The shader worker thread does it because it needs to communicate with other processes through the file system
			FPlatformProcess::Sleep(.010f);
		}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompiler.cpp:5611

Scope (from outer to inner):

file
function     FShaderCompilingManager::FShaderCompilingManager

Source code excerpt:

	// Read values from the engine ini
	verify(GConfig->GetBool( TEXT("DevOptions.Shaders"), TEXT("bAllowCompilingThroughWorkers"), bAllowCompilingThroughWorkers, GEngineIni ));
	verify(GConfig->GetBool( TEXT("DevOptions.Shaders"), TEXT("bAllowAsynchronousShaderCompiling"), bAllowAsynchronousShaderCompiling, GEngineIni ));

	// Explicitly load ShaderPreprocessor module so it will run its initialization step
	FModuleManager::LoadModuleChecked<IModuleInterface>(TEXT("ShaderPreprocessor"));
	
	// override the use of workers, can be helpful for debugging shader compiler code
	static const IConsoleVariable* CVarAllowCompilingThroughWorkers = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shaders.AllowCompilingThroughWorkers"), false);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompiler.cpp:5625

Scope (from outer to inner):

file
function     FShaderCompilingManager::FShaderCompilingManager

Source code excerpt:

	if (!FPlatformProcess::SupportsMultithreading())
	{
		bAllowAsynchronousShaderCompiling = false;
	}

	verify(GConfig->GetInt( TEXT("DevOptions.Shaders"), TEXT("MaxShaderJobBatchSize"), MaxShaderJobBatchSize, GEngineIni ));
	verify(GConfig->GetBool( TEXT("DevOptions.Shaders"), TEXT("bPromptToRetryFailedShaderCompiles"), bPromptToRetryFailedShaderCompiles, GEngineIni ));
	verify(GConfig->GetBool(TEXT("DevOptions.Shaders"), TEXT("bDebugBreakOnPromptToRetryShaderCompile"), bDebugBreakOnPromptToRetryShaderCompile, GEngineIni));
	verify(GConfig->GetBool( TEXT("DevOptions.Shaders"), TEXT("bLogJobCompletionTimes"), bLogJobCompletionTimes, GEngineIni ));

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompiler.cpp:6393

Scope (from outer to inner):

file
function     void FShaderCompilingManager::BlockOnShaderMapCompletion

Source code excerpt:


	COOK_STAT(FScopedDurationTimer BlockingTimer(ShaderCompilerCookStats::BlockingTimeSec));
	if (bAllowAsynchronousShaderCompiling)
	{
		// Calculate how many shader jobs there are total to provide the slow task with the correct amount of work.
		int NumJobs = 0;
		{
			FScopeLock Lock(&CompileQueueSection);
			for (int32 ShaderMapIndex = 0; ShaderMapIndex < ShaderMapIdsToFinishCompiling.Num(); ShaderMapIndex++)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompiler.cpp:6526

Scope (from outer to inner):

file
function     void FShaderCompilingManager::BlockOnAllShaderMapCompletion

Source code excerpt:


	COOK_STAT(FScopedDurationTimer BlockingTimer(ShaderCompilerCookStats::BlockingTimeSec));
	if (bAllowAsynchronousShaderCompiling)
	{
		// Calculate how many shader jobs there are total to provide the slow task with the correct amount of work.
		int NumJobs = 0;
		{
			FScopeLock Lock(&CompileQueueSection);
			for (TMap<int32, FPendingShaderMapCompileResultsPtr>::TIterator It(ShaderMapJobs); It; ++It)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShaderCompiler.h:714

Scope (from outer to inner):

file
class        class FShaderCompilingManager : IAssetCompilingManager

Source code excerpt:

	bool bAllowCompilingThroughWorkers;
	/** Whether to allow shaders to compile in the background or to block after each material. */
	bool bAllowAsynchronousShaderCompiling;
	/** Whether to ask to retry a failed shader compile error. */
	bool bPromptToRetryFailedShaderCompiles;
	/** If enabled when we enter the prompt to retry we will break in the debugger if one is attached rather than prompting. */
	bool bDebugBreakOnPromptToRetryShaderCompile = false;
	/** Whether to log out shader job completion times on the worker thread.  Useful for tracking down which global shader is taking a long time. */
	bool bLogJobCompletionTimes;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShaderCompiler.h:832

Scope (from outer to inner):

file
class        class FShaderCompilingManager : IAssetCompilingManager
function     bool AllowAsynchronousShaderCompiling

Source code excerpt:

	bool AllowAsynchronousShaderCompiling() const 
	{
		return bAllowAsynchronousShaderCompiling;
	}

	/** 
	 * Returns whether async compiling is happening.
	 * Note: This is dependent on NumOutstandingJobs which is updated from another thread, so the results are non-deterministic.
	 */