r.RDG.Debug

r.RDG.Debug

#Overview

name: r.RDG.Debug

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

It is referenced in 15 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.RDG.Debug is to enable debugging and warning output for inefficiencies in the Render Dependency Graph (RDG) system during the wiring and execution of render passes. This setting variable is primarily used for the rendering system, specifically for debugging and optimizing render graph operations.

The Unreal Engine subsystem that relies on this setting variable is the Render Dependency Graph (RDG) system, which is part of the rendering pipeline. It is used in various parts of the RenderCore module, as evidenced by the callsites in RenderGraphPrivate.cpp, RenderGraphEvent.cpp, and RenderGraphValidation.cpp.

The value of this variable is set through the console variable system (CVarRDGDebug) and can also be set via command line arguments. It is initialized to 0 by default and can be changed at runtime.

The associated variable GRDGDebug interacts directly with r.RDG.Debug, sharing the same value. This internal variable is used throughout the codebase to check the debug state and control behavior accordingly.

Developers must be aware that enabling this variable (setting it to 1 or 2) may impact performance due to additional checks and warning emissions. It should primarily be used during development and debugging phases, not in production builds.

Best practices when using this variable include:

  1. Use it temporarily during development to identify inefficiencies in render graph operations.
  2. Set it to 1 for warnings to be emitted once, or 2 for warnings to be emitted every time an issue is detected.
  3. Disable it (set to 0) for production builds to avoid performance overhead.
  4. Use in conjunction with other RDG debugging tools and variables for comprehensive analysis.

Regarding the associated variable GRDGDebug: The purpose of GRDGDebug is to serve as an internal representation of the r.RDG.Debug console variable. It is used throughout the rendering code to quickly check the debug state without having to query the console variable system each time.

GRDGDebug is used in various parts of the RenderCore module, controlling behavior such as:

The value of GRDGDebug is set by the console variable system and can also be influenced by command line arguments (e.g., “-rdgdebug”).

Developers should be aware that GRDGDebug’s value directly affects rendering performance and behavior. It should be used cautiously and primarily during development and debugging phases.

Best practices for using GRDGDebug include:

  1. Avoid modifying it directly; instead, use the r.RDG.Debug console variable to change its value.
  2. Be aware of its performance implications when enabled.
  3. Use it in conjunction with other debugging tools and variables for comprehensive render graph analysis.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.cpp:28

Scope: file

Source code excerpt:

int32 GRDGDebug = 0;
FAutoConsoleVariableRef CVarRDGDebug(
	TEXT("r.RDG.Debug"),
	GRDGDebug,
	TEXT("Allow to output warnings for inefficiencies found during wiring and execution of the passes.\n")
	TEXT(" 0: disabled;\n")
	TEXT(" 1: emit warning once (default);\n")
	TEXT(" 2: emit warning everytime issue is detected."),
	ECVF_RenderThreadSafe);

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Public/RenderGraphPass.h:361

Scope (from outer to inner):

file
class        class FRDGPass

Source code excerpt:

	virtual void Execute(FRHIComputeCommandList& RHICmdList) {}

	// When r.RDG.Debug is enabled, this will include a full namespace path with event scopes included.
	IF_RDG_ENABLE_DEBUG(FString FullPathIfDebug);

	const FRDGEventName Name;
	const FRDGParameterStruct ParameterStruct;
	const ERDGPassFlags Flags;
	const ERHIPipeline Pipeline;

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphEvent.cpp:512

Scope (from outer to inner):

file
function     bool GetEmitRDGEvents

Source code excerpt:

	bRDGChannelEnabled = UE_TRACE_CHANNELEXPR_IS_ENABLED(RDGChannel);
#endif // RDG_ENABLE_TRACE
	return GRDGEvents != 0 && (GRDGEmitDrawEvents_RenderThread != 0 || GRDGDebug != 0 || bRDGChannelEnabled != 0);
#else
	return false;
#endif
}

#if RDG_EVENTS == RDG_EVENTS_STRING_COPY

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.cpp:26

Scope: file

Source code excerpt:

	ECVF_RenderThreadSafe);

int32 GRDGDebug = 0;
FAutoConsoleVariableRef CVarRDGDebug(
	TEXT("r.RDG.Debug"),
	GRDGDebug,
	TEXT("Allow to output warnings for inefficiencies found during wiring and execution of the passes.\n")
	TEXT(" 0: disabled;\n")
	TEXT(" 1: emit warning once (default);\n")
	TEXT(" 2: emit warning everytime issue is detected."),
	ECVF_RenderThreadSafe);

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.cpp:223

Scope (from outer to inner):

file
function     void EmitRDGWarning

Source code excerpt:

void EmitRDGWarning(const FString& WarningMessage)
{
	if (!GRDGDebug)
	{
		return;
	}

	static TSet<FString> GAlreadyEmittedWarnings;

	const int32 kRDGEmitWarningsOnce = 1;

	if (GRDGDebug == kRDGEmitWarningsOnce)
	{
		if (!GAlreadyEmittedWarnings.Contains(WarningMessage))
		{
			GAlreadyEmittedWarnings.Add(WarningMessage);
			UE_LOG(LogRDG, Warning, TEXT("%s"), *WarningMessage);

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.cpp:529

Scope (from outer to inner):

file
function     void InitRenderGraph

Source code excerpt:

	if (FParse::Param(FCommandLine::Get(), TEXT("rdgdebug")))
	{
		GRDGDebug = 1;
	}

	if (FParse::Param(FCommandLine::Get(), TEXT("rdgdebugextendresourcelifetimes")))
	{
		GRDGDebugExtendResourceLifetimes = 1;
	}

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.cpp:631

Scope (from outer to inner):

file
function     bool IsParallelExecuteEnabled

Source code excerpt:

		&& !GRHICommandList.Bypass()
		&& !IsImmediateMode()
		&& !GRDGDebug
		&& !GRDGDebugFlushGPU
		&& !GRDGTransitionLog
		&& !IsMobilePlatform(GMaxRHIShaderPlatform)
		&& !IsOpenGLPlatform(GMaxRHIShaderPlatform)
		&& !IsVulkanMobileSM5Platform(GMaxRHIShaderPlatform)
		&& GRHISupportsMultithreadedShaderCreation

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.cpp:651

Scope (from outer to inner):

file
function     bool IsParallelSetupEnabled

Source code excerpt:

		&& !GRHICommandList.Bypass()
		&& !IsImmediateMode()
		&& !GRDGDebug
		&& !GRDGTransitionLog
		&& !IsMobilePlatform(GMaxRHIShaderPlatform)
		&& !IsOpenGLPlatform(GMaxRHIShaderPlatform)
		&& !IsVulkanMobileSM5Platform(GMaxRHIShaderPlatform)
		&& GRHISupportsMultithreadedShaderCreation
#if WITH_DUMPGPU

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.h:32

Scope: file

Source code excerpt:

extern int32 GRDGClobberResources;
extern int32 GRDGValidation;
extern int32 GRDGDebug;
extern int32 GRDGDebugFlushGPU;
extern int32 GRDGDebugExtendResourceLifetimes;
extern int32 GRDGDebugDisableTransientResources;
extern int32 GRDGBreakpoint;
extern int32 GRDGTransitionLog;
extern int32 GRDGImmediateMode;

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphPrivate.h:95

Scope: file

Source code excerpt:

const int32 GRDGClobberResources = 0;
const int32 GRDGValidation = 0;
const int32 GRDGDebug = 0;
const int32 GRDGDebugFlushGPU = 0;
const int32 GRDGDebugExtendResourceLifetimes = 0;
const int32 GRDGDebugDisableTransientResources = 0;
const int32 GRDGBreakpoint = 0;
const int32 GRDGTransitionLog = 0;
const int32 GRDGImmediateMode = 0;

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphValidation.cpp:173

Scope (from outer to inner):

file
function     void FRDGUserValidation::ValidateCreateTexture

Source code excerpt:

	ValidateCreateViewableResource(Texture);
	Texture->TextureDebugData = Allocator.AllocNoDestruct<FRDGTextureDebugData>();
	if (GRDGDebug)
	{
		TrackedTextures.Add(Texture);
	}
}

void FRDGUserValidation::ValidateCreateBuffer(FRDGBufferRef Buffer)

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphValidation.cpp:191

Scope (from outer to inner):

file
function     void FRDGUserValidation::ValidateCreateBuffer

Source code excerpt:


	Buffer->BufferDebugData = Allocator.Alloc<FRDGBufferDebugData>();
	if (GRDGDebug)
	{
		TrackedBuffers.Add(Buffer);
	}
}

void FRDGUserValidation::ValidateCreateSRV(FRDGTextureSRVRef SRV)

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphValidation.cpp:1050

Scope (from outer to inner):

file
function     void FRDGUserValidation::ValidateExecuteEnd

Source code excerpt:

	GRDGBuilderActive = false;

	if (GRDGDebug && GRDGValidation)
	{
		auto ValidateResourceAtExecuteEnd = [](const FRDGViewableResource* Resource)
		{
			const auto& ViewableDebugData = Resource->GetViewableDebugData();
			const bool bProducedButNeverUsed = ViewableDebugData.PassAccessCount == 1 && ViewableDebugData.FirstProducer;

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphValidation.cpp:1110

Scope (from outer to inner):

file
function     void FRDGUserValidation::ValidateExecutePassBegin

Source code excerpt:

	SetAllowRHIAccess(Pass, true);

	if (GRDGDebug)
	{
		Pass->GetParameters().EnumerateUniformBuffers([&](FRDGUniformBufferBinding UniformBuffer)
		{
			// Global uniform buffers are always marked as used, because FShader traversal doesn't know about them.
			if (UniformBuffer.IsStatic())
			{

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderGraphValidation.cpp:1212

Scope (from outer to inner):

file
function     void FRDGUserValidation::ValidateExecutePassEnd

Source code excerpt:

	const FRDGParameterStruct PassParameters = Pass->GetParameters();

	if (GRDGDebug)
	{
		uint32 TrackedResourceCount = 0;
		uint32 UsedResourceCount = 0;

		PassParameters.Enumerate([&](FRDGParameter Parameter)
		{