r.Nanite.PersistentThreadsCulling

r.Nanite.PersistentThreadsCulling

#Overview

name: r.Nanite.PersistentThreadsCulling

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

It is referenced in 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.Nanite.PersistentThreadsCulling is to control the culling method used in Unreal Engine’s Nanite system, specifically for node and cluster culling operations. This setting is part of the rendering system, particularly the Nanite geometry system.

This setting variable is primarily used in the Nanite rendering subsystem of Unreal Engine 5. Based on the callsites, it’s referenced in the NaniteCullRaster.cpp file, which is part of the Renderer module.

The value of this variable is set through a console variable (CVar) system. It’s initialized with a default value of 0, meaning it’s disabled by default. Developers can change this value at runtime or through configuration files.

The associated variable CVarNanitePersistentThreadsCulling directly interacts with r.Nanite.PersistentThreadsCulling. They share the same value and are used interchangeably in the code.

Developers must be aware of several important aspects when using this variable:

  1. When enabled (set to 1), it performs node and cluster culling in one combined kernel using persistent threads.
  2. This method doesn’t scale threads with GPU size and relies on scheduler behavior, which may not be optimal for non-fixed hardware platforms.
  3. It’s automatically disabled on Apple Silicon devices due to lack of forward progress guarantee support.

Best practices for using this variable include:

  1. Keep it disabled (0) for most scenarios, especially on non-fixed hardware platforms.
  2. Only enable it if you’ve thoroughly tested and confirmed performance benefits on your target hardware.
  3. Be cautious when enabling it on mobile or varying hardware configurations.
  4. Always test performance impacts when changing this setting.

Regarding the associated variable CVarNanitePersistentThreadsCulling:

The purpose of CVarNanitePersistentThreadsCulling is the same as r.Nanite.PersistentThreadsCulling. It’s the actual console variable implementation that controls the persistent threads culling feature in the Nanite system.

This variable is used within the Nanite namespace in the Renderer module. It’s checked in various functions related to node and cluster culling, as well as in draw geometry operations.

The value of CVarNanitePersistentThreadsCulling is set through the console variable system and can be accessed using the GetValueOnRenderThread() method.

Developers should be aware that this variable directly controls the behavior of the culling system and can significantly impact performance and rendering behavior. The same best practices and considerations mentioned for r.Nanite.PersistentThreadsCulling apply to CVarNanitePersistentThreadsCulling as well.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:243

Scope: file

Source code excerpt:


static TAutoConsoleVariable<int32> CVarNanitePersistentThreadsCulling(
	TEXT("r.Nanite.PersistentThreadsCulling"),
	0,
	TEXT("Perform node and cluster culling in one combined kernel using persistent threads.")
	TEXT("It doesn't scale threads with GPU size and relies on scheduler behavior, so it is not recommended for non-fixed hardware platforms."),
	ECVF_RenderThreadSafe
);

#Loc: <Workspace>/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRHI.cpp:392

Scope: file

Source code excerpt:

            
            // Disable persistent threads on Apple Silicon (as it doesn't support forward progress guarantee).
            IConsoleVariable* NanitePersistentThreadCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Nanite.PersistentThreadsCulling"));
            if (NanitePersistentThreadCVar != nullptr && NanitePersistentThreadCVar->GetInt() == 1)
            {
                NanitePersistentThreadCVar->Set(0);
            }
        }
	}

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:242

Scope: file

Source code excerpt:

);

static TAutoConsoleVariable<int32> CVarNanitePersistentThreadsCulling(
	TEXT("r.Nanite.PersistentThreadsCulling"),
	0,
	TEXT("Perform node and cluster culling in one combined kernel using persistent threads.")
	TEXT("It doesn't scale threads with GPU size and relies on scheduler behavior, so it is not recommended for non-fixed hardware platforms."),
	ECVF_RenderThreadSafe
);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:3313

Scope (from outer to inner):

file
namespace    Nanite
function     void FRenderer::AddPass_NodeAndClusterCull

Source code excerpt:

	check(ViewsBuffer);

	if (CVarNanitePersistentThreadsCulling.GetValueOnRenderThread())
	{
		AddPass_NodeAndClusterCull(
			RDG_EVENT_NAME("PersistentCull"),
			SharedParameters,
			nullptr,
			nullptr,

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:5243

Scope (from outer to inner):

file
namespace    Nanite
function     void FRenderer::DrawGeometry

Source code excerpt:


		const TCHAR* BufferName = TEXT("Nanite.MainAndPostNodesAndClusterBatchesBuffer");
		if(CVarNanitePersistentThreadsCulling.GetValueOnRenderThread())
		{
			// They only have to be initialized once as the culling code reverts nodes/batches to their cleared state after they have been consumed.
			MainAndPostNodesAndClusterBatchesBuffer = CreateBufferOnce( GraphBuilder, GGlobalResources.MainAndPostNodesAndClusterBatchesBuffer.Buffer, Desc, BufferName,
				[&]( FRDGBufferRef Buffer )
				{
					AddPassInitNodesAndClusterBatchesUAV( GraphBuilder, SharedContext.ShaderMap, GraphBuilder.CreateUAV( Buffer ) );