r.RHICmdFlushRenderThreadTasks

r.RHICmdFlushRenderThreadTasks

#Overview

name: r.RHICmdFlushRenderThreadTasks

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

It is referenced in 8 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.RHICmdFlushRenderThreadTasks is to control the flushing of render thread tasks for issue diagnosis in Unreal Engine 5. It serves as a main switch for more granular console variables related to render thread task flushing.

This setting variable is primarily used in the rendering system of Unreal Engine 5. Based on the callsites, it is utilized in various rendering subsystems, including:

  1. Base Pass Rendering
  2. Depth Rendering
  3. Shadow Depth Rendering
  4. Translucent Rendering
  5. Velocity Rendering

The value of this variable is set through the TAutoConsoleVariable system in Unreal Engine. It is initialized with a default value of 0 in the RHICommandList.cpp file.

Several other variables interact with r.RHICmdFlushRenderThreadTasks:

  1. CVarRHICmdFlushRenderThreadTasksBasePass
  2. CVarRHICmdFlushRenderThreadTasksPrePass
  3. CVarRHICmdFlushRenderThreadTasksShadowPass
  4. CVarRHICmdFlushRenderThreadTasksTranslucentPass
  5. CVarRHICmdFlushRenderThreadTasksVelocityPass

These variables are used in conjunction with r.RHICmdFlushRenderThreadTasks to control task flushing for specific rendering passes.

Developers must be aware that enabling this variable (setting it to a value greater than 0) will cause the engine to flush render thread tasks every pass. This can significantly impact performance and should only be used for issue diagnosis.

Best practices when using this variable include:

  1. Keep it disabled (set to 0) during normal development and gameplay.
  2. Enable it only when diagnosing specific rendering issues.
  3. Use in combination with the more granular variables for targeted debugging of specific rendering passes.

Regarding the associated variable CVarRHICmdFlushRenderThreadTasks:

The purpose of CVarRHICmdFlushRenderThreadTasks is identical to r.RHICmdFlushRenderThreadTasks. It is the internal representation of the console variable within the engine’s C++ code.

This variable is used directly in the rendering subsystems to check whether task flushing should be performed. It is typically accessed using the GetValueOnRenderThread() method to ensure thread-safe access to its current value.

The best practices and considerations for CVarRHICmdFlushRenderThreadTasks are the same as those for r.RHICmdFlushRenderThreadTasks, as they represent the same setting within the engine.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/RHI/Private/RHICommandList.cpp:48

Scope: file

Source code excerpt:


TAutoConsoleVariable<int32> CVarRHICmdFlushRenderThreadTasks(
	TEXT("r.RHICmdFlushRenderThreadTasks"),
	0,
	TEXT("If true, then we flush the render thread tasks every pass. For issue diagnosis. This is a main switch for more granular cvars."));

static TAutoConsoleVariable<int32> CVarRHICmdMergeSmallDeferredContexts(
	TEXT("r.RHICmdMergeSmallDeferredContexts"),
	1,

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/RHI/Private/RHICommandList.cpp:47

Scope: file

Source code excerpt:

	TEXT("Controls the task granularity of a great number of things in the parallel renderer."));

TAutoConsoleVariable<int32> CVarRHICmdFlushRenderThreadTasks(
	TEXT("r.RHICmdFlushRenderThreadTasks"),
	0,
	TEXT("If true, then we flush the render thread tasks every pass. For issue diagnosis. This is a main switch for more granular cvars."));

static TAutoConsoleVariable<int32> CVarRHICmdMergeSmallDeferredContexts(
	TEXT("r.RHICmdMergeSmallDeferredContexts"),

#Loc: <Workspace>/Engine/Source/Runtime/RHI/Public/RHICommandList.h:170

Scope: file

Source code excerpt:

extern RHI_API bool GEnableAsyncCompute;
extern RHI_API TAutoConsoleVariable<int32> CVarRHICmdWidth;
extern RHI_API TAutoConsoleVariable<int32> CVarRHICmdFlushRenderThreadTasks;


struct FRHICopyTextureInfo
{
	FIntRect GetSourceRect() const
	{

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp:196

Scope (from outer to inner):

file
function     static bool IsBasePassWaitForTasksEnabled

Source code excerpt:

static bool IsBasePassWaitForTasksEnabled()
{
	return CVarRHICmdFlushRenderThreadTasksBasePass.GetValueOnRenderThread() > 0 || CVarRHICmdFlushRenderThreadTasks.GetValueOnRenderThread() > 0;
}

static bool IsStandardTranslucenyPassSeparated()
{
	static const auto TranslucencyStandardSeparatedCVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.Translucency.StandardSeparated"));
	return TranslucencyStandardSeparatedCVar && TranslucencyStandardSeparatedCVar->GetValueOnAnyThread() != 0;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DepthRendering.cpp:166

Scope (from outer to inner):

file
function     static bool IsDepthPassWaitForTasksEnabled

Source code excerpt:

static bool IsDepthPassWaitForTasksEnabled()
{
	return CVarRHICmdFlushRenderThreadTasksPrePass.GetValueOnRenderThread() > 0 || CVarRHICmdFlushRenderThreadTasks.GetValueOnRenderThread() > 0;
}



template <bool bPositionOnly>
bool GetDepthPassShaders(

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowDepthRendering.cpp:1059

Scope (from outer to inner):

file
function     static bool IsShadowDepthPassWaitForTasksEnabled

Source code excerpt:

static bool IsShadowDepthPassWaitForTasksEnabled()
{
	return CVarRHICmdFlushRenderThreadTasksShadowPass.GetValueOnRenderThread() > 0 || CVarRHICmdFlushRenderThreadTasks.GetValueOnRenderThread() > 0;
}

BEGIN_SHADER_PARAMETER_STRUCT(FShadowDepthPassParameters, )
	SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
	SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FMobileShadowDepthPassUniformParameters, MobilePassUniformBuffer)
	SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FShadowDepthPassUniformParameters, DeferredPassUniformBuffer)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/TranslucentRendering.cpp:216

Scope (from outer to inner):

file
function     static bool IsTranslucencyWaitForTasksEnabled

Source code excerpt:

static bool IsTranslucencyWaitForTasksEnabled()
{
	return IsParallelTranslucencyEnabled() && (CVarRHICmdFlushRenderThreadTasksTranslucentPass.GetValueOnRenderThread() > 0 || CVarRHICmdFlushRenderThreadTasks.GetValueOnRenderThread() > 0);
}

bool IsSeparateTranslucencyEnabled(ETranslucencyPass::Type TranslucencyPass, float DownsampleScale)
{
	// Currently AfterDOF is rendered earlier in the frame and must be rendered in a separate texture.
	if (   TranslucencyPass == ETranslucencyPass::TPT_TranslucencyAfterDOF

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VelocityRendering.cpp:428

Scope (from outer to inner):

file
function     bool FVelocityRendering::IsVelocityWaitForTasksEnabled

Source code excerpt:

bool FVelocityRendering::IsVelocityWaitForTasksEnabled(EShaderPlatform ShaderPlatform)
{
	return FVelocityRendering::IsParallelVelocity(ShaderPlatform) && (CVarRHICmdFlushRenderThreadTasksVelocityPass.GetValueOnRenderThread() > 0 || CVarRHICmdFlushRenderThreadTasks.GetValueOnRenderThread() > 0);
}

bool FVelocityMeshProcessor::PrimitiveHasVelocityForView(const FViewInfo& View, const FPrimitiveSceneProxy* PrimitiveSceneProxy)
{
	// Skip camera cuts which effectively reset velocity for the new frame.
	if (View.bCameraCut && !View.PreviousViewTransform.IsSet())