PoolSize
PoolSize
#Overview
name: PoolSize
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 67
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of PoolSize is to define the size of a memory pool for resource allocation in various subsystems of Unreal Engine 5. It is commonly used to set the size of texture pools, buffer pools, and other resource pools in the rendering and memory management systems.
Based on the provided code snippets, PoolSize is utilized in several Unreal Engine subsystems, plugins, and modules:
- Rendering system (D3D11, D3D12, Vulkan, OpenGL)
- Texture streaming system
- Buffer allocation system
- Landscape editing system
- Movie Pipeline rendering system
- PCG (Procedural Content Generation) system
- Replication Graph system
The value of PoolSize is typically set in one of the following ways:
- Calculated as a percentage of total available VRAM (GPoolSizeVRAMPercentage)
- Set through configuration files or command-line arguments
- Defined as a constant value for specific subsystems
- Determined dynamically based on system capabilities or requirements
PoolSize often interacts with other variables such as:
- GTexturePoolSize: The total size of the texture pool
- MaxAllocationSize: The maximum size of a single allocation from the pool
- TotalGraphicsMemory: The total available graphics memory
- MemoryBudget: The memory budget for streaming assets
Developers should be aware of the following when using PoolSize:
- Setting an appropriate PoolSize is crucial for optimal performance and memory usage
- Too small a PoolSize may lead to frequent allocations and deallocations, impacting performance
- Too large a PoolSize may waste memory, especially on systems with limited resources
- Different subsystems may have different optimal PoolSize values
Best practices when using PoolSize include:
- Adjusting PoolSize based on the target hardware and specific application requirements
- Monitoring memory usage and performance to fine-tune PoolSize
- Using dynamic allocation strategies when possible to adapt to different hardware configurations
- Considering the trade-offs between memory usage and performance when setting PoolSize
- Documenting the rationale behind chosen PoolSize values for different subsystems
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:1811, section: [TextureStreaming]
- INI Section:
TextureStreaming
- Raw value:
160
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineRenderPasses/Private/MoviePipelineDeferredPasses.cpp:249
Scope (from outer to inner):
file
function void UMoviePipelineDeferredPassBase::SetupImpl
Source code excerpt:
// the accumulators can be tied up for multiple game frames, thus we must have at least one per output and we can only reuse them between
// actual output frames (not engine frames). This doesn't allocate memory until they're actually used so it's ok to over-allocate.
int32 PoolSize = (TotalNumberOfAccumulators + (ActivePostProcessMaterials.Num()*NumCameras) + 1) * 3;
AccumulatorPool = MakeShared<TAccumulatorPool<FImageOverlappedAccumulator>, ESPMode::ThreadSafe>(PoolSize);
PreviousCustomDepthValue.Reset();
PreviousDumpFramesValue.Reset();
PreviousColorFormatValue.Reset();
// This scene view extension will be released automatically as soon as Render Sequence is torn down.
#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/RuntimeGen/PCGRuntimeGenScheduler.cpp:96
Scope (from outer to inner):
file
function void FPCGRuntimeGenScheduler::Tick
Source code excerpt:
}
// Initialize RuntimeGen PA pool if necessary. If PoolSize is 0, then we have not initialized the pool yet.
if (!GenSources.IsEmpty() || !GeneratedComponents.IsEmpty())
{
if (PartitionActorPoolSize == 0 && PCGRuntimeGenSchedulerHelpers::CVarRuntimeGenerationEnablePooling.GetValueOnAnyThread())
{
AddPartitionActorPoolCount(PCGRuntimeGenSchedulerHelpers::CVarRuntimeGenerationBasePoolSize.GetValueOnAnyThread());
}
#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/RuntimeGen/PCGRuntimeGenScheduler.cpp:691
Scope (from outer to inner):
file
function void FPCGRuntimeGenScheduler::TickCVars
Source code excerpt:
bPoolingWasEnabledLastFrame = bPoolingEnabled;
// Handle when the base PA PoolSize is modified. Cleanup all local components and reset the pool with the correct number of PAs.
if (PCGRuntimeGenSchedulerHelpers::CVarRuntimeGenerationEnablePooling.GetValueOnAnyThread())
{
// Don't allow a pool size <= 0
const uint32 BasePoolSize = FMath::Max(1, PCGRuntimeGenSchedulerHelpers::CVarRuntimeGenerationBasePoolSize.GetValueOnAnyThread());
if (BasePoolSizeLastFrame != BasePoolSize)
#Loc: <Workspace>/Engine/Plugins/Runtime/ReplicationGraph/Source/Private/ReplicationGraphTypes.cpp:49
Scope: file
Source code excerpt:
void LogStats(int32 Mode, FOutputDevice& Ar=*GLog);
/** Logs details about a specific list */
void LogDetails(int32 PoolSize, int32 BlockIdx, int32 ListIdx, FOutputDevice& Ar=*GLog);
void CountBytes(FArchive& Ar) const
{
PoolTable.CountBytes(Ar);
for (const FPool& Pool : PoolTable)
{
#Loc: <Workspace>/Engine/Plugins/Runtime/ReplicationGraph/Source/Private/ReplicationGraphTypes.cpp:264
Scope (from outer to inner):
file
function void PrintRepListDetails
Source code excerpt:
GActorListAllocator.LogStats(mode, Ar);
}
void PrintRepListDetails(int32 PoolSize, int32 BlockIdx, int32 ListIdx)
{
GActorListAllocator.LogDetails(PoolSize, BlockIdx, ListIdx);
}
#endif
void PreAllocateRepList(int32 ListSize, int32 NumLists)
{
// nothing
#Loc: <Workspace>/Engine/Plugins/Runtime/ReplicationGraph/Source/Private/ReplicationGraphTypes.cpp:395
Scope (from outer to inner):
file
function void TActorListAllocator<NumListsPerBlock, MaxNumPools>::LogDetails
Source code excerpt:
template<uint32 NumListsPerBlock, uint32 MaxNumPools>
void TActorListAllocator<NumListsPerBlock, MaxNumPools>::LogDetails(int32 PoolSize, int32 BlockIdx, int32 ListIdx, FOutputDevice& Ar)
{
FPool* Pool = PoolTable.FindByPredicate([&PoolSize](const FPool& InPool) { return PoolSize <= InPool.ListSize; });
if (!Pool)
{
Ar.Logf(TEXT("Could not find suitable PoolSize %d"), PoolSize);
return;
}
if (ListIdx > NumListsPerBlock)
{
Ar.Logf(TEXT("ListIdx %d too big. Should be <= %d."), ListIdx, NumListsPerBlock);
#Loc: <Workspace>/Engine/Plugins/Runtime/ReplicationGraph/Source/Public/ReplicationGraphTypes.h:511
Scope: file
Source code excerpt:
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
// Intended to be called from immediate mode window while debugging
extern "C" DLLEXPORT void PrintRepListDetails(int32 PoolSize, int32 BlockIdx, int32 ListIdx);
extern "C" DLLEXPORT void PrintRepListStats(int32 mode=0);
void PrintRepListStatsAr(int32 mode, FOutputDevice& Ar=*GLog);
#endif
#Loc: <Workspace>/Engine/Source/Developer/Zen/Internal/ZenClient.h:58
Scope (from outer to inner):
file
namespace UE::Zen
class class IZenClientPool
Source code excerpt:
virtual ~IZenClientPool() = default;
virtual bool Connect(FStringView Host, int32 Port, int32 PoolSize = 8) = 0;
virtual void Disconnect() = 0;
virtual bool IsConnected() const = 0;
virtual bool SendRequest(FCbPackage&& Request, FOnStreamResponse&& OnResponse) = 0;
virtual bool SendRequest(FCbObject&& Request, FOnStreamResponse&& OnResponse) = 0;
virtual bool SendStreamRequest(FCbObject&& Request, FOnStreamResponse&& OnStreamResponse) = 0;
#Loc: <Workspace>/Engine/Source/Developer/Zen/Private/ZenClient.cpp:683
Scope (from outer to inner):
file
namespace UE::Zen
class class FZenClientPool final : public IZenClientPool
Source code excerpt:
virtual ~FZenClientPool();
virtual bool Connect(FStringView Host, int32 Port, int32 PoolSize = 8) override;
virtual void Disconnect() override;
virtual inline bool IsConnected() const override { return bConnected; }
virtual bool SendRequest(FCbPackage&& Request, FOnStreamResponse&& OnResponse) override;
virtual bool SendRequest(FCbObject&& Request, FOnStreamResponse&& OnResponse) override;
#Loc: <Workspace>/Engine/Source/Developer/Zen/Private/ZenClient.cpp:732
Scope (from outer to inner):
file
namespace UE::Zen
function bool FZenClientPool::Connect
Source code excerpt:
}
bool FZenClientPool::Connect(FStringView Host, int32 Port, int32 PoolSize)
{
check(bConnected == false);
Pool.SetNum(PoolSize);
for (FPoolEntry& Entry : Pool)
{
if (Entry.Client.Connect(Host, Port) == false)
{
return false;
#Loc: <Workspace>/Engine/Source/Developer/Zen/Private/ZenClient.cpp:756
Scope (from outer to inner):
file
namespace UE::Zen
function bool FZenClientPool::Connect
Source code excerpt:
PoolHead = PoolTail = &Pool[0];
for (int32 Index = 1; Index < PoolSize; ++Index)
{
Pool[Index].Next = PoolTail;
PoolTail = &Pool[Index];
}
#endif
#Loc: <Workspace>/Engine/Source/Developer/Zen/Private/ZenClient.cpp:825
Scope (from outer to inner):
file
namespace UE::Zen
function FZenClientPool::FPoolEntry* FZenClientPool::GetClient
Source code excerpt:
#if UE_WITH_ZEN_NON_BLOCKING_POOL
const int32 PoolSize = Pool.Num();
int32 EntryIndex = PoolEntryStartIndex.IncrementExchange() % PoolSize;
int32 SpinCount = 0;
for (;;)
{
FPoolEntry& Entry = Pool[EntryIndex];
#Loc: <Workspace>/Engine/Source/Developer/Zen/Private/ZenClient.cpp:842
Scope (from outer to inner):
file
namespace UE::Zen
function FZenClientPool::FPoolEntry* FZenClientPool::GetClient
Source code excerpt:
}
EntryIndex = (EntryIndex + 1) % PoolSize;
if (++SpinCount >= PoolSize * 2)
{
SpinCount = 0;
FPlatformProcess::Sleep(0.01f);
}
}
#else
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestObjectPool.cpp:19
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
FPool::FPtr Ptr = Pool.Alloc(3);
const int32 PoolSize = Pool.GetAllocatedSize();
for(int32 i = 0; i < 32; ++i)
{
Pool.Free(Ptr);
Ptr = Pool.Alloc(4);
}
// Make sure the freelist is working - should only ever have 3 elements allocated
EXPECT_EQ(PoolSize, Pool.GetAllocatedSize());
EXPECT_EQ(Pool.GetNumAllocatedBlocks(), 1);
}
GTEST_TEST(ObjectPoolTests, TestPool_CompoundType)
{
// Tests Alloc/Free works with class types
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestObjectPool.cpp:55
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
FPool::FPtr Ptr = Pool.Alloc(3, 3.0f);
const int32 PoolSize = Pool.GetAllocatedSize();
for(int32 i = 0; i < 32; ++i)
{
Pool.Free(Ptr);
Ptr = Pool.Alloc(4, 4.0f);
}
// Make sure the freelist is working - should only ever have 3 elements allocated
EXPECT_EQ(PoolSize, Pool.GetAllocatedSize());
EXPECT_EQ(Pool.GetNumAllocatedBlocks(), 1);
}
GTEST_TEST(ObjectPoolTests, TestPool_ComplexType)
{
// Tests Alloc/Free works with non-trivial types
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestObjectPool.cpp:101
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
FPool::FPtr Ptr = Pool.Alloc(ConstructorCount, DestructorCount);
const int32 PoolSize = Pool.GetAllocatedSize();
for(int32 i = 0; i < 32; ++i)
{
Pool.Free(Ptr);
Ptr = Pool.Alloc(ConstructorCount, DestructorCount);
}
// Make sure the freelist is working - should only ever have 3 elements allocated
EXPECT_EQ(PoolSize, Pool.GetAllocatedSize());
EXPECT_EQ(Pool.GetNumAllocatedBlocks(), 1);
// Make sure when types require destructors they area actually called
EXPECT_EQ(ConstructorCount, 35);
EXPECT_EQ(DestructorCount, 32);
}
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestObjectPool.cpp:132
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
}
const int32 PoolSize = Pool.GetAllocatedSize();
Pool.Reset();
for(int32 i = 0; i < 32; ++i)
{
Pool.Alloc(i);
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestObjectPool.cpp:142
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
// Make sure reset works, the allocated size should never change as we only need one block
EXPECT_EQ(PoolSize, Pool.GetAllocatedSize());
EXPECT_EQ(Pool.GetNumAllocatedBlocks(), 1);
}
GTEST_TEST(ObjectPoolTests, TestPool_ComplexType_Reset)
{
// Tests calling Reset on the pool with items that require destruction actually destructs the items
#Loc: <Workspace>/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRHI.cpp:530
Scope: file
Source code excerpt:
if ( GPoolSizeVRAMPercentage > 0 && MemoryStats.TotalGraphicsMemory > 0 )
{
float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(MemoryStats.TotalGraphicsMemory);
// Truncate GTexturePoolSize to MB (but still counted in bytes)
GTexturePoolSize = int64(FGenericPlatformMath::TruncToFloat(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024;
UE_LOG(LogRHI,Log,TEXT("Texture pool is %llu MB (%d%% of %llu MB)"),
GTexturePoolSize / 1024 / 1024,
GPoolSizeVRAMPercentage,
MemoryStats.TotalGraphicsMemory / 1024 / 1024);
}
#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/AutoRTFM/ObjectPool.h:7
Scope (from outer to inner):
file
namespace AutoRTFM
Source code excerpt:
{
template<typename T, size_t PoolSize>
class TObjectPool
{
public:
TObjectPool() = default;
T* Allocate()
#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/AutoRTFM/ObjectPool.h:22
Scope (from outer to inner):
file
namespace AutoRTFM
class class TObjectPool
function T* Allocate
Source code excerpt:
}
ASSERT(HighWatermark < PoolSize);
return Lines + HighWatermark++;
}
void Deallocate(T* Line)
{
FFreeNode* FreeNode = reinterpret_cast<FFreeNode*>(Line);
#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/AutoRTFM/ObjectPool.h:39
Scope (from outer to inner):
file
namespace AutoRTFM
class class TObjectPool
Source code excerpt:
};
T Lines[PoolSize];
size_t HighWatermark{0};
FFreeNode* NextFree{nullptr};
};
} // namespace AutoRTFM
#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/HAL/MallocBinned.cpp:603
Scope (from outer to inner):
file
function static FPoolInfo* AllocatePoolMemory
Source code excerpt:
}
static FPoolInfo* AllocatePoolMemory(FMallocBinned& Allocator, FPoolTable* Table, uint32 PoolSize, uint16 TableIndex)
{
const uint32 PageSize = Allocator.PageSize;
// Must create a new pool.
uint32 Blocks = PoolSize / Table->BlockSize;
uint32 Bytes = Blocks * Table->BlockSize;
UPTRINT OsBytes = Align(Bytes, PageSize);
checkSlow(Blocks >= 1);
checkSlow(PoolSize >= Bytes);
FFreeMem* Free = nullptr;
SIZE_T ActualPoolSize; //TODO: use this to reduce waste?
#if USE_OS_SMALL_BLOCK_GRAB_MEMORY_FROM_OS
Free = GetAllocFromSmallBlockGrab(Allocator, OsBytes);
#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Misc/ConfigCacheIni.cpp:1368
Scope (from outer to inner):
file
function void FConfigFile::OverrideFromCommandline
Source code excerpt:
// -ini:IniName:[Section1]:Key1=Value1,[Section2]:Key2=Value2
// for example:
// -ini:Engine:[/Script/Engine.Engine]:bSmoothFrameRate=False,[TextureStreaming]:PoolSize=100
// (will update the cache after the final combined engine.ini)
const TCHAR* CommandlineStream = FCommandLine::Get();
while(FParse::Value(CommandlineStream, *FString::Printf(TEXT("%s%s"), CommandlineOverrideSpecifiers::IniSwitchIdentifier, *FPaths::GetBaseFilename(Filename)), Settings, false))
{
// break apart on the commas
TArray<FString> SettingPairs;
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Allocation.cpp:1429
Scope (from outer to inner):
file
function FD3D12BufferPool* FD3D12DefaultBufferAllocator::CreateBufferPool
Source code excerpt:
const FString Name(L"D3D12 Pool Allocator");
EResourceAllocationStrategy AllocationStrategy = FD3D12PoolAllocator::GetResourceAllocationStrategy(InResourceFlags, InResourceStateMode, Alignment);
uint64 PoolSize = InHeapType == D3D12_HEAP_TYPE_READBACK ? READBACK_BUFFER_POOL_DEFAULT_POOL_SIZE : BUFFER_POOL_DEFAULT_POOL_SIZE;
uint64 PoolAlignment = (AllocationStrategy == EResourceAllocationStrategy::kPlacedResource) ? MIN_PLACED_RESOURCE_SIZE : kD3D12ManualSubAllocationAlignment;
uint64 MaxAllocationSize = InHeapType == D3D12_HEAP_TYPE_READBACK ? READBACK_BUFFER_POOL_MAX_ALLOC_SIZE : BUFFER_POOL_DEFAULT_POOL_MAX_ALLOC_SIZE;
FRHIMemoryPool::EFreeListOrder FreeListOrder = FRHIMemoryPool::EFreeListOrder::SortBySize;
// Disable defrag if not Default memory
bool bDefragEnabled = (InitConfig.HeapType == D3D12_HEAP_TYPE_DEFAULT);
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Allocation.cpp:1446
Scope (from outer to inner):
file
function FD3D12BufferPool* FD3D12DefaultBufferAllocator::CreateBufferPool
Source code excerpt:
// Use custom pool and allocation size for RT structures because they don't defrag and will thus 'waste' more memory
PoolSize = BUFFER_POOL_RT_ACCELERATION_STRUCTURE_POOL_SIZE;
MaxAllocationSize = BUFFER_POOL_RT_ACCELERATION_STRUCTURE_MAX_ALLOC_SIZE;
}
#endif // D3D12_RHI_RAYTRACING
FD3D12BufferPool* NewPool = new FD3D12PoolAllocator(Device, GetVisibilityMask(), InitConfig, Name, AllocationStrategy, PoolSize, PoolAlignment, MaxAllocationSize, FreeListOrder, bDefragEnabled, TraceHeapId);
#else // USE_BUFFER_POOL_ALLOCATOR
EResourceAllocationStrategy AllocationStrategy = FD3D12DefaultBufferPool::GetResourceAllocationStrategy(InResourceFlags, InResourceStateMode, Alignment);
// if placed then 64KB alignment required :(
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Allocation.cpp:1725
Scope (from outer to inner):
file
function FD3D12TextureAllocatorPool::FD3D12TextureAllocatorPool
Source code excerpt:
const FString Name(L"D3D12 ReadOnly4K Texture Pool Allocator");
uint64 PoolSize = 4 * 1024 * 1024;
uint64 MaxAllocationSize = PoolSize;
bool bDefragEnabled = false; // Disable defrag on 4K pool because it shouldn't really fragment - all allocations are 4K or multiple of 4K and pretty small
FD3D12PoolAllocator* ReadOnly4KPool = new FD3D12PoolAllocator(Device, GetVisibilityMask(), InitConfig, Name, AllocationStrategy, PoolSize, D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT, MaxAllocationSize, FreeListOrder, bDefragEnabled, TraceHeapId);
ReadOnly4KPool->Initialize();
PoolAllocators[(int)EPoolType::ReadOnly4K] = ReadOnly4KPool;
}
{
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Allocation.cpp:1739
Scope (from outer to inner):
file
function FD3D12TextureAllocatorPool::FD3D12TextureAllocatorPool
Source code excerpt:
const FString Name(L"D3D12 ReadOnly Texture Pool Allocator");
uint64 PoolSize = GD3D12PoolAllocatorReadOnlyTextureVRAMPoolSize;
uint64 MaxAllocationSize = GD3D12PoolAllocatorReadOnlyTextureVRAMMaxAllocationSize;
bool bDefragEnabled = true;
FD3D12PoolAllocator* ReadOnlyPool = new FD3D12PoolAllocator(Device, GetVisibilityMask(), InitConfig, Name, AllocationStrategy, PoolSize, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, MaxAllocationSize, FreeListOrder, bDefragEnabled, TraceHeapId);
ReadOnlyPool->Initialize();
PoolAllocators[(int)EPoolType::ReadOnly] = ReadOnlyPool;
}
{
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Allocation.cpp:1753
Scope (from outer to inner):
file
function FD3D12TextureAllocatorPool::FD3D12TextureAllocatorPool
Source code excerpt:
const FString Name(L"D3D12 RT Texture Pool Allocator");
uint64 PoolSize = GD3D12PoolAllocatorRTUAVTextureVRAMPoolSize;
uint64 MaxAllocationSize = GD3D12PoolAllocatorRTUAVTextureVRAMMaxAllocationSize;
// FD3D12ResourceLocation::OnAllocationMoved doesn't correctly retrieve the clear value when recreating moved resources, so we need to disable defrag for this pool for the time being.
bool bDefragEnabled = false;
FD3D12PoolAllocator* RTPool = new FD3D12PoolAllocator(Device, GetVisibilityMask(), InitConfig, Name, AllocationStrategy, PoolSize, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, MaxAllocationSize, FreeListOrder, bDefragEnabled, TraceHeapId);
RTPool->Initialize();
PoolAllocators[(int)EPoolType::RenderTarget] = RTPool;
}
{
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Allocation.cpp:1768
Scope (from outer to inner):
file
function FD3D12TextureAllocatorPool::FD3D12TextureAllocatorPool
Source code excerpt:
const FString Name(L"D3D12 UAV Texture Pool Allocator");
uint64 PoolSize = GD3D12PoolAllocatorRTUAVTextureVRAMPoolSize;
uint64 MaxAllocationSize = GD3D12PoolAllocatorRTUAVTextureVRAMMaxAllocationSize;
// Defrag doesn't correctly handle resources which need the BCn/UINT UAV aliasing workaround, so we'll turn off defrag for this heap for now.
bool bDefragEnabled = false;
FD3D12PoolAllocator* UAVPool = new FD3D12PoolAllocator(Device, GetVisibilityMask(), InitConfig, Name, AllocationStrategy, PoolSize, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, MaxAllocationSize, FreeListOrder, bDefragEnabled, TraceHeapId);
UAVPool->Initialize();
PoolAllocators[(int)EPoolType::UAV] = UAVPool;
}
}
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12PoolAllocator.cpp:49
Scope (from outer to inner):
file
function void FD3D12MemoryPool::Init
Source code excerpt:
void FD3D12MemoryPool::Init()
{
if (PoolSize == 0)
{
return;
}
FD3D12Device* Device = GetParentDevice();
FD3D12Adapter* Adapter = Device->GetParentAdapter();
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12PoolAllocator.cpp:67
Scope (from outer to inner):
file
function void FD3D12MemoryPool::Init
Source code excerpt:
D3D12_HEAP_DESC Desc = {};
Desc.SizeInBytes = PoolSize;
Desc.Properties = HeapProps;
Desc.Alignment = 0;
Desc.Flags = InitConfig.HeapFlags;
// All all resources types on heap when tracking allocations (need to be able to create a buffer on it to extract the base gpu address)
// (Tier 2 support already checked when this flag is enabled)
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12PoolAllocator.cpp:107
Scope (from outer to inner):
file
function void FD3D12MemoryPool::Init
Source code excerpt:
LLM_SCOPED_PAUSE_TRACKING_FOR_TRACKER(ELLMTracker::Default, ELLMAllocType::System);
const D3D12_HEAP_PROPERTIES HeapProps = CD3DX12_HEAP_PROPERTIES(InitConfig.HeapType, GetGPUMask().GetNative(), GetVisibilityMask().GetNative());
VERIFYD3D12RESULT(Adapter->CreateBuffer(HeapProps, GetGPUMask(), InitConfig.InitialResourceState, ED3D12ResourceStateMode::SingleState, InitConfig.InitialResourceState, PoolSize, BackingResource.GetInitReference(), TEXT("Resource Allocator Underlying Buffer"), InitConfig.ResourceFlags));
#if UE_MEMORY_TRACE_ENABLED
MemoryTrace_MarkAllocAsHeap(BackingResource->GetGPUVirtualAddress(), TraceHeapId);
#endif
}
if (IsCPUAccessible(InitConfig.HeapType))
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12PoolAllocator.cpp:135
Scope (from outer to inner):
file
function void FD3D12MemoryPool::Init
Source code excerpt:
#endif // D3D12_RHI_RAYTRACING
LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT_BYTAG(D3D12AllocatorUnused, int64(PoolSize), ELLMTracker::Platform, ELLMAllocType::System);
FRHIMemoryPool::Init();
}
void FD3D12MemoryPool::Destroy()
{
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12PoolAllocator.cpp:560
Scope (from outer to inner):
file
function FRHIMemoryPool* FD3D12PoolAllocator::CreateNewPool
Source code excerpt:
// Find out the pool size - use default, but if allocation doesn't fit then round up to next power of 2
// so it 'always' fits the pool allocator
uint32 PoolSize = DefaultPoolSize;
if (InMinimumAllocationSize > PoolSize)
{
check(InMinimumAllocationSize <= MaxAllocationSize);
PoolSize = FMath::Min(FMath::RoundUpToPowerOfTwo(InMinimumAllocationSize), (uint32)MaxAllocationSize);
}
FD3D12MemoryPool* NewPool = new FD3D12MemoryPool(GetParentDevice(), GetVisibilityMask(), InitConfig,
Name, AllocationStrategy, InPoolIndex, PoolSize, PoolAlignment, InAllocationResourceType, FreeListOrder, TraceHeapId);
NewPool->Init();
return NewPool;
}
bool FD3D12PoolAllocator::HandleDefragRequest(FRHICommandListBase& RHICmdList, FRHIPoolAllocationData* InSourceBlock, FRHIPoolAllocationData& InTmpTargetBlock)
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Texture.cpp:679
Scope (from outer to inner):
file
function void FD3D12DynamicRHI::RHIGetTextureMemoryStats
Source code excerpt:
{
// The texture pool size is a percentage of GTotalGraphicsMemory.
const float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(OutStats.TotalGraphicsMemory);
// Truncate texture pool size to MB (but still counted in bytes).
DesiredTexturePoolSize = int64(FGenericPlatformMath::TruncToFloat(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024;
}
// Make sure the desired texture pool size doesn't make us go overbudget.
const bool bIsLimitedTexturePoolSize = GTexturePoolSize > 0;
const int64 LimitedMaxTexturePoolSize = bIsLimitedTexturePoolSize ? GTexturePoolSize : INT64_MAX;
const int64 MaxTexturePoolSize = FMath::Min(PreviousTexturePoolSize + AvailableSpace - BudgetPadding, LimitedMaxTexturePoolSize); // Max texture pool size without going overbudget or the pre-defined max.
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/Windows/WindowsD3D12Device.cpp:1640
Scope (from outer to inner):
file
function void FD3D12DynamicRHI::Init
Source code excerpt:
if (GPoolSizeVRAMPercentage > 0)
{
float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(FD3D12GlobalStats::GTotalGraphicsMemory);
// Truncate GTexturePoolSize to MB (but still counted in bytes)
GTexturePoolSize = int64(FGenericPlatformMath::TruncToFloat(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024;
UE_LOG(LogRHI, Log, TEXT("Texture pool is %llu MB (%d%% of %llu MB)"),
GTexturePoolSize / 1024 / 1024,
GPoolSizeVRAMPercentage,
FD3D12GlobalStats::GTotalGraphicsMemory / 1024 / 1024);
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/AsyncTextureStreaming.cpp:572
Scope (from outer to inner):
file
function void FRenderAssetStreamingMipCalcTask::UpdateBudgetedMips_Async
Source code excerpt:
const int64 NonStreamingRenderAssetMemory = AllocatedMemory - MemoryUsed + MemoryUsedByNonTextures;
int64 AvailableMemoryForStreaming = PoolSize - NonStreamingRenderAssetMemory - MemoryMargin;
// If the platform defines a max VRAM usage, check if the pool size must be reduced,
// but also check if it would be safe to some of the NonStreamingRenderAssetMemory from the pool size computation.
// The later helps significantly in low budget settings, where NonStreamingRenderAssetMemory would take too much of the pool.
if (GPoolSizeVRAMPercentage > 0 && TotalGraphicsMemory > 0)
{
const int64 UsableVRAM = FMath::Max<int64>(TotalGraphicsMemory * GPoolSizeVRAMPercentage / 100, TotalGraphicsMemory - Settings.VRAMPercentageClamp * 1024ll * 1024ll);
const int64 UsedVRAM = (int64)GRHIGlobals.NonStreamingTextureMemorySizeInKB * 1024ll + NonStreamingRenderAssetMemory; // Add any other...
const int64 AvailableVRAMForStreaming = FMath::Min<int64>(UsableVRAM - UsedVRAM - MemoryMargin, PoolSize);
if (Settings.bLimitPoolSizeToVRAM || AvailableVRAMForStreaming > AvailableMemoryForStreaming)
{
AvailableMemoryForStreaming = AvailableVRAMForStreaming;
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/AsyncTextureStreaming.cpp:943
Scope (from outer to inner):
file
function void FRenderAssetStreamingMipCalcTask::UpdateStats_Async
Source code excerpt:
TArray<FStreamingRenderAsset>& StreamingRenderAssets = StreamingManager.AsyncUnsafeStreamingRenderAssets;
Stats.RenderAssetPool = PoolSize;
// Stats.StreamingPool = MemoryBudget;
Stats.UsedStreamingPool = 0;
Stats.SafetyPool = MemoryMargin;
Stats.TemporaryPool = TempMemoryBudget;
Stats.StreamingPool = MemoryBudget;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/AsyncTextureStreaming.cpp:1081
Scope (from outer to inner):
file
function void FRenderAssetStreamingMipCalcTask::UpdateCSVOnlyStats_Async
Source code excerpt:
FRenderAssetStreamingStats& Stats = StreamingManager.GatheredStats;
Stats.RenderAssetPool = PoolSize;
Stats.SafetyPool = MemoryMargin;
Stats.TemporaryPool = TempMemoryBudget;
Stats.StreamingPool = MemoryBudget;
Stats.NonStreamingMips = AllocatedMemory;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/AsyncTextureStreaming.h:146
Scope (from outer to inner):
file
class class FRenderAssetStreamingMipCalcTask : public FNonAbandonableTask
function void Reset
Source code excerpt:
TotalGraphicsMemory = InTotalGraphicsMemory;
AllocatedMemory = InAllocatedMemory;
PoolSize = InPoolSize;
TempMemoryBudget = InTempMemoryBudget;
MemoryMargin = InMemoryMargin;
bAbort = false;
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/AsyncTextureStreaming.h:228
Scope (from outer to inner):
file
class class FRenderAssetStreamingMipCalcTask : public FNonAbandonableTask
Source code excerpt:
/** Size of the pool once non streaming data is removed and value is stabilized */
int64 PoolSize;
/** How much temp memory is allowed (temp memory is taken when changing mip count). */
int64 TempMemoryBudget;
/** How much temp memory is allowed (temp memory is taken when changing mip count). */
int64 MemoryMargin;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:135
Scope (from outer to inner):
file
function FRenderAssetStreamingManager::FRenderAssetStreamingManager
Source code excerpt:
int32 PoolSizeIniSetting = 0;
GConfig->GetInt(TEXT("TextureStreaming"), TEXT("PoolSize"), PoolSizeIniSetting, GEngineIni);
GConfig->GetBool(TEXT("TextureStreaming"), TEXT("UseDynamicStreaming"), bUseDynamicStreaming, GEngineIni);
GConfig->GetFloat( TEXT("TextureStreaming"), TEXT("BoostPlayerTextures"), BoostPlayerTextures, GEngineIni );
GConfig->GetBool(TEXT("TextureStreaming"), TEXT("NeverStreamOutRenderAssets"), GNeverStreamOutRenderAssets, GEngineIni);
// -NeverStreamOutRenderAssets
if (FParse::Param(FCommandLine::Get(), TEXT("NeverStreamOutRenderAssets")))
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/TextureStreamingHelpers.cpp:311
Scope (from outer to inner):
file
function void FRenderAssetStreamingSettings::Update
Source code excerpt:
HLODStrategy = CVarStreamingHLODStrategy.GetValueOnAnyThread();
GlobalMipBias = !GIsEditor ? FMath::FloorToInt(FMath::Max<float>(0.f, CVarStreamingMipBias.GetValueOnAnyThread())) : 0;
PoolSize = CVarStreamingPoolSize.GetValueOnAnyThread();
MeshPoolSize = CVarStreamingPoolSizeForMeshes.GetValueOnAnyThread();
bUsePerTextureBias = CVarStreamingUsePerTextureBias.GetValueOnAnyThread() != 0;
bUseNewMetrics = CVarStreamingUseNewMetrics.GetValueOnAnyThread() != 0;
bLimitPoolSizeToVRAM = !GIsEditor && CVarStreamingLimitPoolSizeToVRAM.GetValueOnAnyThread() != 0;
bFullyLoadUsedTextures = CVarStreamingFullyLoadUsedTextures.GetValueOnAnyThread() != 0;
bFullyLoadMeshes = CVarStreamingFullyLoadMeshes.GetValueOnAnyThread() != 0;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/TextureStreamingHelpers.h:99
Scope: file
Source code excerpt:
float MaxHiddenPrimitiveViewBoost;
int32 GlobalMipBias;
int32 PoolSize;
int32 MeshPoolSize;
bool bLimitPoolSizeToVRAM;
bool bUseNewMetrics;
bool bFullyLoadUsedTextures;
bool bFullyLoadMeshes;
bool bUseAllMips;
#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Private/LandscapeEditReadback.cpp:235
Scope (from outer to inner):
file
class class FLandscapeEditReadbackTaskPool : public FRenderResource
function void GarbageCollect
Source code excerpt:
void GarbageCollect()
{
const uint32 PoolSize = Pool.Num();
if (PoolSize > 0)
{
// Garbage collect a maximum of one item per call to reduce overhead if pool has grown large.
FLandscapeEditReadbackTaskImpl* Task = &Pool[FrameCount % PoolSize];
if (Task->InitFrameId + 100 < FrameCount)
{
if (Task->TextureResource != nullptr)
{
// Task not completed after 100 updates. We are probably leaking tasks!
UE_LOG(LogLandscape, Warning, TEXT("Leaking landscape edit layer read back tasks."))
#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Private/LandscapePhysicalMaterial.cpp:507
Scope (from outer to inner):
file
class class FLandscapePhysicalMaterialRenderTaskPool : public FRenderResource
function void GarbageCollect
Source code excerpt:
void GarbageCollect()
{
const uint32 PoolSize = Pool.Num();
if (PoolSize > 0)
{
// Garbage collect a maximum of one item per call to reduce overhead if pool has grown large.
FLandscapePhysicalMaterialRenderTaskImpl* Task = &Pool[FrameCount % PoolSize];
// Only garbage collect tasks that are at least 100 frames old (allows resources to be re-used for some time)
if (Task->InitFrameId + 100 < FrameCount)
{
if (Task->LandscapeComponent != nullptr)
{
#Loc: <Workspace>/Engine/Source/Runtime/OpenGLDrv/Private/OpenGLDevice.cpp:1473
Scope (from outer to inner):
file
function void FOpenGLDynamicRHI::Init
Source code excerpt:
if ( GPoolSizeVRAMPercentage > 0 )
{
float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(GOpenGLTotalGraphicsMemory);
// Truncate GTexturePoolSize to MB (but still counted in bytes)
GTexturePoolSize = int64(FGenericPlatformMath::TruncToInt(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024;
UE_LOG(LogRHI, Log, TEXT("Texture pool is %llu MB (%d%% of %llu MB)"),
GTexturePoolSize / 1024 / 1024,
GPoolSizeVRAMPercentage,
GOpenGLTotalGraphicsMemory / 1024 / 1024);
}
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Private/RHICoreTransientResourceAllocator.cpp:1296
Scope (from outer to inner):
file
function FRHITransientPagePool* FRHITransientPagePoolCache::Acquire
Source code excerpt:
PagePoolInitializer.PageSize = Initializer.PageSize;
if (LiveList.IsEmpty() && Initializer.PoolSizeFirst > Initializer.PoolSize)
{
PagePoolInitializer.PageCount = Initializer.PoolSizeFirst / Initializer.PageSize;
}
else
{
PagePoolInitializer.PageCount = Initializer.PoolSize / Initializer.PageSize;
}
FRHITransientPagePool* PagePool = CreatePagePool(PagePoolInitializer);
check(PagePool);
TotalMemoryCapacity += PagePool->GetCapacity();
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Private/RHIPoolAllocator.cpp:278
Scope (from outer to inner):
file
function FRHIMemoryPool::FRHIMemoryPool
Source code excerpt:
FRHIMemoryPool::FRHIMemoryPool(int16 InPoolIndex, uint64 InPoolSize, uint32 InPoolAlignment, ERHIPoolResourceTypes InSupportedResourceTypes, EFreeListOrder InFreeListOrder) :
PoolIndex(InPoolIndex),
PoolSize(InPoolSize),
PoolAlignment(InPoolAlignment),
SupportedResourceTypes(InSupportedResourceTypes),
FreeListOrder(InFreeListOrder),
FreeSize(0),
AligmnentWaste(0),
AllocatedBlocks(0)
{
// PoolSize should fit in 32 bits because FRHIPoolAllocationData only stores 32bit size
check(PoolSize < UINT32_MAX);
}
FRHIMemoryPool::~FRHIMemoryPool()
{
// Can't currently validate because Engine is still leaking too much during shutdown sadly enough
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Private/RHIPoolAllocator.cpp:297
Scope (from outer to inner):
file
function FRHIMemoryPool::~FRHIMemoryPool
Source code excerpt:
check(AllocatedBlocks == 0);
check(AligmnentWaste == 0);
check(FreeSize == PoolSize);
check(FreeBlocks.Num() == 1);
check(FreeBlocks[0]->GetSize() == PoolSize);
*/
Validate();
}
void FRHIMemoryPool::Init()
{
FreeSize = PoolSize;
// Setup a few working free blocks
AllocationDataPool.Reserve(DesiredAllocationPoolSize);
for (int32 Index = 0; Index < DesiredAllocationPoolSize; ++Index)
{
FRHIPoolAllocationData* AllocationData = new FRHIPoolAllocationData();
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Private/RHIPoolAllocator.cpp:322
Scope (from outer to inner):
file
function void FRHIMemoryPool::Init
Source code excerpt:
HeadBlock.InitAsHead(PoolIndex);
FRHIPoolAllocationData* FreeBlock = GetNewAllocationData();
FreeBlock->InitAsFree(PoolIndex, PoolSize, PoolAlignment, 0);
HeadBlock.AddAfter(FreeBlock);
FreeBlocks.Add(FreeBlock);
Validate();
}
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Private/RHIPoolAllocator.cpp:614
Scope (from outer to inner):
file
function void FRHIMemoryPool::Validate
Source code excerpt:
}
check(TotalFreeSize + TotalAllocatedSize == PoolSize);
check(TotalFreeSize == FreeSize);
check(TotalAllocatedSize == GetUsedSize());
// Validate the free blocks
TotalFreeSize = 0;
for (int32 FreeBlockIndex = 0; FreeBlockIndex < FreeBlocks.Num(); ++FreeBlockIndex)
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Public/RHICoreTransientResourceAllocator.h:979
Scope (from outer to inner):
file
class class FRHITransientPagePoolCache : public IRHITransientMemoryCache
Source code excerpt:
// Size in bytes of the pool. Must be a multiple of PageSize.
uint64 PoolSize = 0;
// Size in bytes of the first pool. Only takes effect if larger than PoolSize.
uint64 PoolSizeFirst = 0;
// Size of each page.
uint32 PageSize = 0;
// The latency between the completed fence value and the used fence value to invoke garbage collection of the heap.
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Public/RHIPoolAllocator.h:156
Scope (from outer to inner):
file
class class FRHIMemoryPool
function uint64 GetPoolSize
Source code excerpt:
// Getters
int16 GetPoolIndex() const { return PoolIndex; }
uint64 GetPoolSize() const { return PoolSize; }
uint64 GetFreeSize() const { return FreeSize; }
uint64 GetUsedSize() const { return (PoolSize - FreeSize); }
uint32 GetAlignmentWaste() const { return AligmnentWaste; }
uint32 GetAllocatedBlocks() const { return AllocatedBlocks; }
ERHIPoolResourceTypes GetSupportedResourceTypes() const { return SupportedResourceTypes; }
bool IsResourceTypeSupported(ERHIPoolResourceTypes InType) const { return EnumHasAnyFlags(SupportedResourceTypes, InType); }
bool IsEmpty() const { return GetUsedSize() == 0; }
bool IsFull() const { return FreeSize == 0; }
#Loc: <Workspace>/Engine/Source/Runtime/RHICore/Public/RHIPoolAllocator.h:186
Scope (from outer to inner):
file
class class FRHIMemoryPool
Source code excerpt:
// Const creation members
int16 PoolIndex;
const uint64 PoolSize;
const uint32 PoolAlignment;
const ERHIPoolResourceTypes SupportedResourceTypes;
const EFreeListOrder FreeListOrder;
// Stats
uint64 FreeSize;
#Loc: <Workspace>/Engine/Source/Runtime/SlateCore/Private/Fonts/SlateSdfGenerator.cpp:546
Scope (from outer to inner):
file
function bool FSlateSdfGeneratorImpl::UpdatePoolSize
Source code excerpt:
{
check(IsInGameThread());
int32 PoolSize = 0;
if (IsSlateSdfTextFeatureEnabled())
{
PoolSize = CVarSlateSdfTextGeneratorPoolSize.GetValueOnGameThread();
if (PoolSize <= 0)
{
PoolSize = FGenericPlatformMisc::NumberOfWorkerThreadsToSpawn();
}
}
int32 OldPoolSize = TasksPool.Num();
if (PoolSize < OldPoolSize)
{
return false;
}
if (PoolSize > OldPoolSize)
{
FreeTasks.Reserve(PoolSize);
StartedTasks.Reserve(PoolSize);
TasksPool.Reserve(PoolSize);
for (int32 Index = OldPoolSize; Index < PoolSize; ++Index)
{
int32 AddedIndex = TasksPool.Add(MakeUnique<FAsyncTask<SdfUtils::FSdfGeneratorTask>>());
check(AddedIndex == Index);
FreeTasks.Push(TasksPool[AddedIndex].Get());
}
}
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanCommandBuffer.cpp:282
Scope (from outer to inner):
file
function inline void FVulkanCmdBuffer::InitializeTimings
Source code excerpt:
// Upload cb's can be submitted multiple times in a single frame, so we use an expanded pool to catch timings
// Any overflow will wrap
const uint32 PoolSize = bIsUploadOnly ? 256 : 32;
Timing->Initialize(PoolSize);
}
}
}
void FVulkanCmdBuffer::AddWaitSemaphore(VkPipelineStageFlags InWaitFlags, TArrayView<VulkanRHI::FSemaphore*> InWaitSemaphores)
{
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanGPUProfiler.h:47
Scope (from outer to inner):
file
class class FVulkanGPUTiming : public FGPUTiming
Source code excerpt:
* Initializes all Vulkan resources.
*/
void Initialize(uint32 PoolSize = 8);
/**
* Releases all Vulkan resources.
*/
void Release();
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanMemory.cpp:2730
Scope (from outer to inner):
file
function bool FMemoryManager::AllocateBufferPooled
Source code excerpt:
const float Priority = CalculateBufferPriority(BufferUsageFlags);
const int32 PoolSize = (int32)GetPoolTypeForAlloc(Size, Alignment);
if (PoolSize != (int32)EPoolSizes::SizesCount)
{
Size = PoolSizes[PoolSize];
}
FScopeLock ScopeLock(&UsedFreeBufferAllocationsLock);
for (int32 Index = 0; Index < UsedBufferAllocations[PoolSize].Num(); ++Index)
{
FVulkanSubresourceAllocator* SubresourceAllocator = UsedBufferAllocations[PoolSize][Index];
if ((SubresourceAllocator->BufferUsageFlags & BufferUsageFlags) == BufferUsageFlags &&
(SubresourceAllocator->MemoryPropertyFlags & MemoryPropertyFlags) == MemoryPropertyFlags)
{
if(SubresourceAllocator->TryAllocate2(OutAllocation, AllocationOwner, Size, Alignment, MetaType, File, Line))
{
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanMemory.cpp:2753
Scope (from outer to inner):
file
function bool FMemoryManager::AllocateBufferPooled
Source code excerpt:
}
for (int32 Index = 0; Index < FreeBufferAllocations[PoolSize].Num(); ++Index)
{
FVulkanSubresourceAllocator* SubresourceAllocator = FreeBufferAllocations[PoolSize][Index];
if ((SubresourceAllocator->BufferUsageFlags & BufferUsageFlags) == BufferUsageFlags &&
(SubresourceAllocator->MemoryPropertyFlags & MemoryPropertyFlags) == MemoryPropertyFlags)
{
if(SubresourceAllocator->TryAllocate2(OutAllocation, AllocationOwner, Size, Alignment, MetaType, File, Line))
{
IncMetaStats(MetaType, OutAllocation.Size);
FreeBufferAllocations[PoolSize].RemoveAtSwap(Index, 1, EAllowShrinking::No);
UsedBufferAllocations[PoolSize].Add(SubresourceAllocator);
return true;
}
}
}
// New Buffer
const uint32 BufferSize = FMath::Max(Size, BufferSizes[PoolSize]);
VkBuffer Buffer;
VkBufferCreateInfo BufferCreateInfo;
ZeroVulkanStruct(BufferCreateInfo, VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
BufferCreateInfo.size = BufferSize;
BufferCreateInfo.usage = BufferUsageFlags;
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanMemory.cpp:2825
Scope (from outer to inner):
file
function bool FMemoryManager::AllocateBufferPooled
Source code excerpt:
}
FVulkanSubresourceAllocator* SubresourceAllocator = new FVulkanSubresourceAllocator(EVulkanAllocationPooledBuffer, this, AllocationFlags, DeviceMemoryAllocation, MemoryTypeIndex,
MemoryPropertyFlags, MemReqs.alignment, Buffer, BufferSize, BufferId, BufferUsageFlags, PoolSize);
RegisterSubresourceAllocator(SubresourceAllocator);
UsedBufferAllocations[PoolSize].Add(SubresourceAllocator);
if(SubresourceAllocator->TryAllocate2(OutAllocation, AllocationOwner, Size, Alignment, MetaType, File, Line))
{
IncMetaStats(MetaType, OutAllocation.Size);
return true;
}
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanMemory.cpp:3399
Scope (from outer to inner):
file
function void FMemoryManager::DumpMemory
Source code excerpt:
{
int PoolSizeIndex = (Index - NumResourceHeaps) % NumSmallAllocators;
uint32 PoolSize = PoolSizeIndex >= (int32)EPoolSizes::SizesCount ? -1 : PoolSizes[PoolSizeIndex];
if(0 == PoolSizeIndex)
{
VULKAN_LOGMEMORY(VULKAN_LOGMEMORY_PAD);
}
WriteLogLine(FString::Printf(TEXT("Pool %d"), PoolSize), Stat);
}
else
{
WriteLogLine(FString::Printf(TEXT("ResourceHeap %d"), Index), Stat);
}
}
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanMemory.h:859
Scope (from outer to inner):
file
namespace VulkanRHI
class class FMemoryManager : public FDeviceChild
function EPoolSizes GetPoolTypeForAlloc
Source code excerpt:
EPoolSizes GetPoolTypeForAlloc(uint32 Size, uint32 Alignment)
{
EPoolSizes PoolSize = EPoolSizes::SizesCount;
if (GVulkanUseBufferBinning != 0)
{
for (int32 i = 0; i < (int32)EPoolSizes::SizesCount; ++i)
{
if (PoolSizes[i] >= Size)
{
PoolSize = (EPoolSizes)i;
break;
}
}
}
return PoolSize;
}
FCriticalSection UsedFreeBufferAllocationsLock;
TArray<FVulkanSubresourceAllocator*> UsedBufferAllocations[(int32)EPoolSizes::SizesCount + 1];
TArray<FVulkanSubresourceAllocator*> FreeBufferAllocations[(int32)EPoolSizes::SizesCount + 1];
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp:553
Scope (from outer to inner):
file
function void FVulkanDynamicRHI::Init
Source code excerpt:
const uint64 TotalGPUMemory = Device->GetDeviceMemoryManager().GetTotalMemory(true);
float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(TotalGPUMemory);
// Truncate GTexturePoolSize to MB (but still counted in bytes)
GTexturePoolSize = int64(FGenericPlatformMath::TruncToFloat(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024;
UE_LOG(LogRHI, Log, TEXT("Texture pool is %llu MB (%d%% of %llu MB)"),
GTexturePoolSize / 1024 / 1024,
GPoolSizeVRAMPercentage,
TotalGPUMemory / 1024 / 1024);
}
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanUtil.cpp:166
Scope (from outer to inner):
file
function void FVulkanGPUTiming::Initialize
Source code excerpt:
* Initializes all Vulkan resources and if necessary, the static variables.
*/
void FVulkanGPUTiming::Initialize(uint32 PoolSize)
{
StaticInitialize(this, PlatformStaticInitialize);
bIsTiming = false;
if (FVulkanPlatform::SupportsTimestampRenderQueries() && GIsSupported)
{
check(!Pool);
Pool = new FVulkanTimingQueryPool(Device, CmdContext->GetCommandBufferManager(), PoolSize);
Pool->ResultsBuffer = Device->GetStagingManager().AcquireBuffer(Pool->GetMaxQueries() * sizeof(uint64) * 2, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Pool->MappedPointer = (uint64*)Pool->ResultsBuffer->GetMappedPointer();
}
}
/**
#Loc: <Workspace>/Engine/Source/Runtime/Windows/D3D11RHI/Private/Windows/WindowsD3D11Device.cpp:1737
Scope (from outer to inner):
file
function void FD3D11DynamicRHI::InitD3DDevice
Source code excerpt:
if ( GPoolSizeVRAMPercentage > 0 )
{
float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(FD3D11GlobalStats::GTotalGraphicsMemory);
// Truncate GTexturePoolSize to MB (but still counted in bytes)
GTexturePoolSize = int64(FGenericPlatformMath::TruncToFloat(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024;
UE_LOG(LogRHI,Log,TEXT("Texture pool is %llu MB (%d%% of %llu MB)"),
GTexturePoolSize / 1024 / 1024,
GPoolSizeVRAMPercentage,
FD3D11GlobalStats::GTotalGraphicsMemory / 1024 / 1024);
}