r.Shaders.BoundsChecking

r.Shaders.BoundsChecking

#Overview

name: r.Shaders.BoundsChecking

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

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

It is referenced in 4 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.Shaders.BoundsChecking is to control whether bounds-checking and flush-to-zero/ignore operations are enforced for buffer reads and writes in shaders. This setting is primarily related to the shader compilation and execution system in Unreal Engine 5.

Unreal Engine’s shader compilation system relies on this setting variable. It is used in the ShaderCompiler module, specifically in the ShaderCompiler.cpp file.

The value of this variable is set through a console variable (CVar) system. It is defined as a TAutoConsoleVariable with a default value of 1 (enabled).

This variable interacts with the shader compilation process. When enabled, it adds the CFLAG_BoundsChecking flag to the shader compiler environment.

Developers must be aware that enabling this variable may impact shader performance, as bounds-checking adds additional instructions to the shader code. However, it can help prevent out-of-bounds memory access in shaders, which can lead to undefined behavior or crashes.

Best practices when using this variable include:

  1. Keeping it enabled during development and testing to catch potential issues.
  2. Consider disabling it for release builds if performance is critical and you’re confident in your shader code’s safety.
  3. Be aware that not all shader languages can omit bounds checking, so the impact may vary depending on the target platform.

Regarding the associated variable CVarShaderBoundsChecking:

The purpose of CVarShaderBoundsChecking is to provide a programmatic interface to the r.Shaders.BoundsChecking setting within the C++ code.

This variable is used in the Engine module, specifically in the ShaderCompiler.cpp file.

The value of CVarShaderBoundsChecking is set when the r.Shaders.BoundsChecking console variable is initialized.

CVarShaderBoundsChecking interacts directly with the shader compilation process. It’s checked in the GlobalBeginCompileShader function to determine whether to add the CFLAG_BoundsChecking flag to the shader compiler environment.

Developers should be aware that changes to CVarShaderBoundsChecking will affect all subsequent shader compilations.

Best practices for using CVarShaderBoundsChecking include:

  1. Use GetValueOnAnyThread() when accessing its value, as shown in the code example.
  2. Consider the performance implications of enabling bounds checking in performance-critical code paths.
  3. Use this variable in conjunction with other shader compilation flags and settings for comprehensive shader control.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseDeviceProfiles.ini:1160, section: [Mac DeviceProfile]

#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:2227

Scope: file

Source code excerpt:


static TAutoConsoleVariable<int32> CVarShaderBoundsChecking(
	TEXT("r.Shaders.BoundsChecking"),
	1,
	TEXT("Whether to enforce bounds-checking & flush-to-zero/ignore for buffer reads & writes in shaders. Defaults to 1 (enabled). Not all shader languages can omit bounds checking."),
	ECVF_ReadOnly);

static TAutoConsoleVariable<int32> CVarShaderWarningsAsErrors(
	TEXT("r.Shaders.WarningsAsErrors"),

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/Shader.cpp:1795

Scope (from outer to inner):

file
function     void ShaderMapAppendKeyString

Source code excerpt:

		}
		{
			static const auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shaders.BoundsChecking"));
			KeyString += (CVar && CVar->GetInt() != 0) ? TEXT("_BoundsChecking") : TEXT("");
		}
		{
			KeyString += RHISupportsManualVertexFetch(Platform) ? TEXT("_MVF_") : TEXT("");
		}
		

#Associated Variable and Callsites

This variable is associated with another variable named CVarShaderBoundsChecking. They share the same value. See the following C++ source code.

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

Scope: file

Source code excerpt:

	ECVF_ReadOnly);

static TAutoConsoleVariable<int32> CVarShaderBoundsChecking(
	TEXT("r.Shaders.BoundsChecking"),
	1,
	TEXT("Whether to enforce bounds-checking & flush-to-zero/ignore for buffer reads & writes in shaders. Defaults to 1 (enabled). Not all shader languages can omit bounds checking."),
	ECVF_ReadOnly);

static TAutoConsoleVariable<int32> CVarShaderWarningsAsErrors(

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

Scope (from outer to inner):

file
function     void GlobalBeginCompileShader

Source code excerpt:

		}

		if (CVarShaderBoundsChecking.GetValueOnAnyThread() != 0)
		{
			Input.Environment.CompilerFlags.Add(CFLAG_BoundsChecking);
		}
		
		// Check whether we can compile metal shaders to bytecode - avoids poisoning the DDC
		static ITargetPlatformManagerModule& TPM = GetTargetPlatformManagerRef();