r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers
r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers
#Overview
name: r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Number of frames after which unused global resource allocations will be discarded. Set 0 to ignore. (default=30)
It is referenced in 5
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers
is to control the lifespan of unused global resource buffers in Unreal Engine’s rendering system. It determines the number of frames after which unused global resource allocations will be discarded.
This setting variable is primarily used in the RenderCore module of Unreal Engine 5. It directly affects the management of dynamic buffers and global render resources.
The value of this variable is set through the console variable system, allowing it to be adjusted at runtime. It’s associated with the C++ variable GGlobalBufferNumFramesUnusedThreshold
, which shares the same value.
The main interactions with this variable occur in the following contexts:
- In
DynamicBufferAllocator.cpp
, it’s used to determine when to release unused dynamic read buffers. - In
GlobalRenderResources.cpp
, it’s used in the garbage collection process for dynamic buffers.
Developers should be aware that:
- Setting this value to 0 will disable the automatic release of unused buffers.
- The default value is 30 frames.
- This variable directly impacts memory usage and performance, as it controls how aggressively the engine releases unused resources.
Best practices when using this variable include:
- Carefully consider the trade-off between memory usage and performance when adjusting this value.
- Monitor memory usage and frame rates when modifying this setting.
- In memory-constrained environments, consider lowering the value to free up resources more quickly.
- In scenarios where rapid reuse of resources is common, a higher value might be beneficial to avoid frequent reallocation.
Regarding the associated variable GGlobalBufferNumFramesUnusedThreshold
:
The purpose of GGlobalBufferNumFramesUnusedThreshold
is to serve as the C++ implementation of the console variable r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers
. It’s used directly in the engine’s C++ code to control the release of unused global resource buffers.
This variable is used in the RenderCore module, specifically in the dynamic buffer allocation and global render resource management systems.
The value of GGlobalBufferNumFramesUnusedThreshold
is set by the console variable system when r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers
is modified.
It interacts primarily with the buffer management systems, determining when buffers should be released based on how long they’ve been unused.
Developers should be aware that modifying this variable directly in C++ code is not recommended, as it may be overwritten by the console variable system.
Best practices for this variable are the same as for r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers
, as they are essentially the same setting exposed in different ways.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/GlobalRenderResources.cpp:18
Scope: file
Source code excerpt:
int32 GGlobalBufferNumFramesUnusedThreshold = 30;
FAutoConsoleVariableRef CVarGlobalBufferNumFramesUnusedThreshold(
TEXT("r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers"),
GGlobalBufferNumFramesUnusedThreshold,
TEXT("Number of frames after which unused global resource allocations will be discarded. Set 0 to ignore. (default=30)"));
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Associated Variable and Callsites
This variable is associated with another variable named GGlobalBufferNumFramesUnusedThreshold
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/DynamicBufferAllocator.cpp:212
Scope (from outer to inner):
file
function static void RemoveUnusedBuffers
Source code excerpt:
static void RemoveUnusedBuffers(FRHICommandListBase* RHICmdList, FDynamicReadBufferPool* BufferPool)
{
extern int32 GGlobalBufferNumFramesUnusedThreshold;
for (int32 BufferIndex = 0, NumBuffers = BufferPool->Buffers.Num(); BufferIndex < NumBuffers; ++BufferIndex)
{
FDynamicAllocReadBuffer& Buffer = BufferPool->Buffers[BufferIndex];
if (Buffer.MappedBuffer != nullptr)
{
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/DynamicBufferAllocator.cpp:222
Scope (from outer to inner):
file
function static void RemoveUnusedBuffers
Source code excerpt:
Buffer.Unlock(*RHICmdList);
}
else if (GGlobalBufferNumFramesUnusedThreshold && !Buffer.AllocatedByteCount)
{
++Buffer.NumFramesUnused;
if (Buffer.NumFramesUnused >= GGlobalBufferNumFramesUnusedThreshold)
{
// Remove the buffer, assumes they are unordered.
Buffer.Release();
BufferPool->Buffers.RemoveAtSwap(BufferIndex);
--BufferIndex;
--NumBuffers;
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/GlobalRenderResources.cpp:16
Scope: file
Source code excerpt:
TEXT("The maximum number of transient vertex buffer bytes to allocate before we start panic logging who is doing the allocations"));
int32 GGlobalBufferNumFramesUnusedThreshold = 30;
FAutoConsoleVariableRef CVarGlobalBufferNumFramesUnusedThreshold(
TEXT("r.NumFramesUnusedBeforeReleasingGlobalResourceBuffers"),
GGlobalBufferNumFramesUnusedThreshold,
TEXT("Number of frames after which unused global resource allocations will be discarded. Set 0 to ignore. (default=30)"));
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Bulk data interface for providing a single color used to initialize a volume texture.
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/GlobalRenderResources.cpp:814
Scope (from outer to inner):
file
function void GarbageCollect
Source code excerpt:
DynamicBufferType* Buffer = LiveList[Index];
if (GGlobalBufferNumFramesUnusedThreshold > 0 && Buffer->LastUsedFrame + GGlobalBufferNumFramesUnusedThreshold <= GFrameCounterRenderThread)
{
TotalAllocatedMemory -= Buffer->BufferSize;
Buffer->ReleaseResource();
LiveList.RemoveAt(Index, 1, EAllowShrinking::No);
FreeList.Remove(Buffer);
delete Buffer;