Skip to content

Commit 6d3df85

Browse files
Jiawei-Shaodawn-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
D3D12: Implement GetAllocatorMemoryInfo()
This patch implements the memory allocation tracking on D3D12 backend just like what memory tracking is done on Vulkan backend. Bug: 407730048 Change-Id: I94130379c1e547a746e8c057f5cfac9ee077f208 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/308395 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
1 parent 594bc62 commit 6d3df85

11 files changed

Lines changed: 106 additions & 56 deletions

src/dawn/native/PooledResourceMemoryAllocator.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,21 @@ void PooledResourceMemoryAllocator::DeallocateResourceHeap(
7575
uint64_t PooledResourceMemoryAllocator::GetPoolSizeForTesting() const {
7676
return mPool.size();
7777
}
78+
79+
void AllocationSizeTracker::Increment(uint64_t incrementSize) {
80+
mTotalSize += incrementSize;
81+
}
82+
83+
void AllocationSizeTracker::Decrement(ExecutionSerial currentSerial, uint64_t decrementSize) {
84+
DAWN_ASSERT(mTotalSize >= decrementSize);
85+
mMemoryToDecrement.Enqueue(decrementSize, currentSerial);
86+
}
87+
88+
void AllocationSizeTracker::Tick(ExecutionSerial completedSerial) {
89+
for (uint64_t size : mMemoryToDecrement.IterateUpTo(completedSerial)) {
90+
DAWN_ASSERT(mTotalSize >= size);
91+
mTotalSize -= size;
92+
}
93+
mMemoryToDecrement.ClearUpTo(completedSerial);
94+
}
7895
} // namespace dawn::native

src/dawn/native/PooledResourceMemoryAllocator.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <memory>
3333

3434
#include "dawn/common/SerialQueue.h"
35+
#include "dawn/native/IntegerTypes.h"
3536
#include "dawn/native/ResourceHeapAllocator.h"
3637
#include "partition_alloc/pointers/raw_ptr.h"
3738

@@ -62,6 +63,24 @@ class PooledResourceMemoryAllocator : public ResourceHeapAllocator {
6263
std::deque<std::unique_ptr<ResourceHeapBase>> mPool;
6364
};
6465

66+
// Wrapper for tracking the allocation sizes to be decremented up to a completed ExecutionSerial
67+
// and reporting total allocation/used sizes.
68+
class AllocationSizeTracker {
69+
public:
70+
// Increment the total size for tracking.
71+
void Increment(uint64_t incrementSize);
72+
// Track the size to be decremented on Tick.
73+
void Decrement(ExecutionSerial currentSerial, uint64_t decrementSize);
74+
// Update the total size after completed serials.
75+
void Tick(ExecutionSerial completedSerial);
76+
77+
uint64_t GetSize() const { return mTotalSize; }
78+
79+
private:
80+
SerialQueue<ExecutionSerial, uint64_t> mMemoryToDecrement;
81+
uint64_t mTotalSize = 0;
82+
};
83+
6584
} // namespace dawn::native
6685

6786
#endif // SRC_DAWN_NATIVE_POOLEDRESOURCEMEMORYALLOCATOR_H_

src/dawn/native/d3d12/DeviceD3D12.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,4 +901,13 @@ const PerStage<std::wstring>& Device::GetDxcShaderProfiles() const {
901901
return mDxcShaderProfiles;
902902
}
903903

904+
AllocatorMemoryInfo Device::GetAllocatorMemoryInfo() const {
905+
DAWN_ASSERT(IsLockedByCurrentThreadIfNeeded());
906+
AllocatorMemoryInfo info = {};
907+
info.totalAllocatedMemory = (*mResourceAllocatorManager)->GetTotalAllocatedMemory();
908+
info.totalUsedMemory = (*mResourceAllocatorManager)->GetTotalUsedMemory();
909+
// D3D12 has no lazy memory concept, leave lazy fields as zero.
910+
return info;
911+
}
912+
904913
} // namespace dawn::native::d3d12

src/dawn/native/d3d12/DeviceD3D12.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ class Device final : public d3d::Device {
164164

165165
uint64_t GetBufferCopyOffsetAlignmentForDepthStencil() const override;
166166

167+
AllocatorMemoryInfo GetAllocatorMemoryInfo() const override;
168+
167169
// Dawn APIs
168170
void SetLabelImpl() override;
169171

src/dawn/native/d3d12/HeapAllocatorD3D12.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <utility>
3131

32+
#include "dawn/native/Queue.h"
3233
#include "dawn/native/d3d/D3DError.h"
3334
#include "dawn/native/d3d12/DeviceD3D12.h"
3435
#include "dawn/native/d3d12/HeapD3D12.h"
@@ -40,11 +41,13 @@ namespace dawn::native::d3d12 {
4041
HeapAllocator::HeapAllocator(Device* device,
4142
ResourceHeapKind resourceHeapKind,
4243
D3D12_HEAP_FLAGS heapFlags,
43-
MemorySegment memorySegment)
44+
MemorySegment memorySegment,
45+
AllocationSizeTracker* allocationMemoryTracker)
4446
: mDevice(device),
4547
mResourceHeapKind(resourceHeapKind),
4648
mHeapFlags(heapFlags),
47-
mMemorySegment(memorySegment) {}
49+
mMemorySegment(memorySegment),
50+
mAllocationMemoryTracker(allocationMemoryTracker) {}
4851

4952
ResultOrError<std::unique_ptr<ResourceHeapBase>> HeapAllocator::AllocateResourceHeap(
5053
uint64_t size) {
@@ -67,6 +70,7 @@ ResultOrError<std::unique_ptr<ResourceHeapBase>> HeapAllocator::AllocateResource
6770

6871
std::unique_ptr<ResourceHeapBase> heapBase =
6972
std::make_unique<Heap>(std::move(d3d12Heap), mMemorySegment, size);
73+
mAllocationMemoryTracker->Increment(size);
7074

7175
// Calling CreateHeap implicitly calls MakeResident on the new heap. We must track this to
7276
// avoid calling MakeResident a second time.
@@ -75,7 +79,10 @@ ResultOrError<std::unique_ptr<ResourceHeapBase>> HeapAllocator::AllocateResource
7579
}
7680

7781
void HeapAllocator::DeallocateResourceHeap(std::unique_ptr<ResourceHeapBase> heap) {
78-
mDevice->ReferenceUntilUnused(static_cast<Heap*>(heap.get())->GetD3D12Heap());
82+
Heap* d3d12Heap = static_cast<Heap*>(heap.get());
83+
mDevice->ReferenceUntilUnused(d3d12Heap->GetD3D12Heap());
84+
mAllocationMemoryTracker->Decrement(mDevice->GetQueue()->GetPendingCommandSerial(),
85+
d3d12Heap->GetSize());
7986
}
8087

8188
} // namespace dawn::native::d3d12

src/dawn/native/d3d12/HeapAllocatorD3D12.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <memory>
3232

3333
#include "dawn/native/D3D12Backend.h"
34+
#include "dawn/native/PooledResourceMemoryAllocator.h"
3435
#include "dawn/native/ResourceHeapAllocator.h"
3536
#include "dawn/native/d3d12/ResourceAllocatorManagerD3D12.h"
3637
#include "dawn/native/d3d12/d3d12_platform.h"
@@ -46,7 +47,8 @@ class HeapAllocator : public ResourceHeapAllocator {
4647
HeapAllocator(Device* device,
4748
ResourceHeapKind resourceHeapKind,
4849
D3D12_HEAP_FLAGS heapFlags,
49-
MemorySegment memorySegment);
50+
MemorySegment memorySegment,
51+
AllocationSizeTracker* allocationMemoryTracker);
5052
~HeapAllocator() override = default;
5153

5254
ResultOrError<std::unique_ptr<ResourceHeapBase>> AllocateResourceHeap(uint64_t size) override;
@@ -57,6 +59,8 @@ class HeapAllocator : public ResourceHeapAllocator {
5759
ResourceHeapKind mResourceHeapKind;
5860
D3D12_HEAP_FLAGS mHeapFlags;
5961
MemorySegment mMemorySegment;
62+
// Owned by ResourceAllocatorManager, which creates and outlives this HeapAllocator.
63+
raw_ptr<AllocationSizeTracker> mAllocationMemoryTracker;
6064
};
6165

6266
} // namespace dawn::native::d3d12

src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,8 @@ ResourceAllocatorManager::ResourceAllocatorManager(Device* device) : mDevice(dev
305305
const ResourceHeapKind resourceHeapKind = static_cast<ResourceHeapKind>(i);
306306
D3D12_HEAP_FLAGS heapFlags = GetD3D12HeapFlags(resourceHeapKind) | createNotZeroedHeapFlag;
307307
mHeapAllocators[i] = std::make_unique<HeapAllocator>(
308-
mDevice, resourceHeapKind, heapFlags, GetMemorySegment(mDevice, resourceHeapKind));
308+
mDevice, resourceHeapKind, heapFlags, GetMemorySegment(mDevice, resourceHeapKind),
309+
&mAllocatedMemory);
309310
mPooledHeapAllocators[i] =
310311
std::make_unique<PooledResourceMemoryAllocator>(mHeapAllocators[i].get());
311312
mSubAllocatedResourceAllocators[i] = std::make_unique<BuddyMemoryAllocator>(
@@ -403,6 +404,9 @@ void ResourceAllocatorManager::Tick(ExecutionSerial completedSerial) {
403404
}
404405
mAllocationsToDelete.ClearUpTo(completedSerial);
405406
mHeapsToDelete.ClearUpTo(completedSerial);
407+
408+
mAllocatedMemory.Tick(completedSerial);
409+
mUsedMemory.Tick(completedSerial);
406410
}
407411

408412
void ResourceAllocatorManager::DeallocateMemory(ResourceHeapAllocation& allocation) {
@@ -420,6 +424,14 @@ void ResourceAllocatorManager::DeallocateMemory(ResourceHeapAllocation& allocati
420424
if (allocation.GetInfo().mMethod == AllocationMethod::kDirect) {
421425
mHeapsToDelete.Enqueue(std::unique_ptr<ResourceHeapBase>(allocation.GetResourceHeap()),
422426
mDevice->GetQueue()->GetPendingCommandSerial());
427+
428+
mUsedMemory.Decrement(mDevice->GetQueue()->GetPendingCommandSerial(),
429+
allocation.GetInfo().mRequestedSize);
430+
mAllocatedMemory.Decrement(mDevice->GetQueue()->GetPendingCommandSerial(),
431+
allocation.GetInfo().mRequestedSize);
432+
} else if (allocation.GetInfo().mMethod == AllocationMethod::kSubAllocated) {
433+
mUsedMemory.Decrement(mDevice->GetQueue()->GetPendingCommandSerial(),
434+
allocation.GetInfo().mRequestedSize);
423435
}
424436

425437
// Invalidate the allocation immediately in case one accidentally
@@ -502,6 +514,8 @@ ResultOrError<ResourceHeapAllocation> ResourceAllocatorManager::CreatePlacedReso
502514
optimizedClearValue, IID_PPV_ARGS(&placedResource)),
503515
"ID3D12Device::CreatePlacedResource"));
504516

517+
mUsedMemory.Increment(resourceInfo.SizeInBytes);
518+
505519
// After CreatePlacedResource has finished, the heap can be unlocked from residency. This
506520
// will insert it into the residency LRU.
507521
mDevice->GetResidencyManager()->UnlockAllocation(heap);
@@ -556,6 +570,9 @@ ResultOrError<ResourceHeapAllocation> ResourceAllocatorManager::CreateCommittedR
556570
optimizedClearValue, IID_PPV_ARGS(&committedResource)),
557571
"ID3D12Device::CreateCommittedResource"));
558572

573+
mAllocatedMemory.Increment(resourceInfo.SizeInBytes);
574+
mUsedMemory.Increment(resourceInfo.SizeInBytes);
575+
559576
// When using CreateCommittedResource, D3D12 creates an implicit heap that contains the
560577
// resource allocation. Because Dawn's memory residency management occurs at the resource
561578
// heap granularity, every directly allocated ResourceHeapAllocation also stores a Heap
@@ -583,4 +600,12 @@ void ResourceAllocatorManager::FreeRecycledAllocations() {
583600
}
584601
}
585602

603+
uint64_t ResourceAllocatorManager::GetTotalAllocatedMemory() const {
604+
return mAllocatedMemory.GetSize();
605+
}
606+
607+
uint64_t ResourceAllocatorManager::GetTotalUsedMemory() const {
608+
return mUsedMemory.GetSize();
609+
}
610+
586611
} // namespace dawn::native::d3d12

src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class ResourceAllocatorManager {
9090

9191
void Tick(ExecutionSerial lastCompletedSerial);
9292

93+
uint64_t GetTotalAllocatedMemory() const;
94+
uint64_t GetTotalUsedMemory() const;
95+
9396
private:
9497
void FreeSubAllocatedMemory(ResourceHeapAllocation& allocation);
9598

@@ -121,6 +124,9 @@ class ResourceAllocatorManager {
121124

122125
SerialQueue<ExecutionSerial, ResourceHeapAllocation> mAllocationsToDelete;
123126
SerialQueue<ExecutionSerial, std::unique_ptr<ResourceHeapBase>> mHeapsToDelete;
127+
128+
AllocationSizeTracker mAllocatedMemory;
129+
AllocationSizeTracker mUsedMemory;
124130
};
125131

126132
} // namespace dawn::native::d3d12

src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -134,28 +134,6 @@ class ResourceMemoryAllocator::SingleTypeAllocator : public ResourceHeapAllocato
134134
BuddyMemoryAllocator mBuddySystem;
135135
};
136136

137-
void ResourceMemoryAllocator::AllocationSizeTracker::Increment(VkDeviceSize incrementSize) {
138-
mTotalSize += incrementSize;
139-
}
140-
141-
void ResourceMemoryAllocator::AllocationSizeTracker::Decrement(ExecutionSerial currentSerial,
142-
VkDeviceSize decrementSize) {
143-
DAWN_ASSERT(mTotalSize >= decrementSize);
144-
mMemoryToDecrement[currentSerial] += decrementSize;
145-
}
146-
147-
void ResourceMemoryAllocator::AllocationSizeTracker::Tick(ExecutionSerial completedSerial) {
148-
auto it = mMemoryToDecrement.begin();
149-
while (it != mMemoryToDecrement.end() && it->first <= completedSerial) {
150-
// Update tracking for allocation/used memory that will be deallocated.
151-
DAWN_ASSERT(mTotalSize >= it->second);
152-
mTotalSize -= it->second;
153-
it++;
154-
}
155-
// Erase the map serials up to the completed serial.
156-
mMemoryToDecrement.erase(mMemoryToDecrement.begin(), it);
157-
}
158-
159137
VkDeviceSize ResourceMemoryAllocator::GetHeapBlockSize(const DawnDeviceAllocatorControl* control) {
160138
static constexpr VkDeviceSize kDefaultHeapBlockSize = 8ull * 1024ull * 1024ull; // 8MiB
161139
VkDeviceSize heapBlockSize = kDefaultHeapBlockSize;
@@ -367,19 +345,19 @@ void ResourceMemoryAllocator::FreeRecycledMemory() {
367345
}
368346

369347
uint64_t ResourceMemoryAllocator::GetTotalUsedMemory() const {
370-
return mUsedMemory.Size();
348+
return mUsedMemory.GetSize();
371349
}
372350

373351
uint64_t ResourceMemoryAllocator::GetTotalAllocatedMemory() const {
374-
return mAllocatedMemory.Size();
352+
return mAllocatedMemory.GetSize();
375353
}
376354

377355
uint64_t ResourceMemoryAllocator::GetTotalLazyAllocatedMemory() const {
378-
return mLazyAllocatedMemory.Size();
356+
return mLazyAllocatedMemory.GetSize();
379357
}
380358

381359
uint64_t ResourceMemoryAllocator::GetTotalLazyUsedMemory() const {
382-
return mLazyUsedMemory.Size();
360+
return mLazyUsedMemory.GetSize();
383361
}
384362

385363
} // namespace dawn::native::vulkan

src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#ifndef SRC_DAWN_NATIVE_VULKAN_RESOURCEMEMORYALLOCATORVK_H_
2929
#define SRC_DAWN_NATIVE_VULKAN_RESOURCEMEMORYALLOCATORVK_H_
3030

31-
#include <map>
3231
#include <memory>
3332
#include <vector>
3433

@@ -83,24 +82,6 @@ class ResourceMemoryAllocator {
8382
void DeallocateResourceHeap(ResourceHeap* heap, bool isLazyMemoryType);
8483

8584
private:
86-
// Wrapper for tracking the allocation sizes to be decremented up to a completed ExecutionSerial
87-
// and reporting total allocation/used sizes.
88-
class AllocationSizeTracker {
89-
public:
90-
// Increment the total size for tracking.
91-
void Increment(VkDeviceSize incrementSize);
92-
// Track the size to be decremented on Tick.
93-
void Decrement(ExecutionSerial currentSerial, VkDeviceSize decrementSize);
94-
// Update the total size after completed serials.
95-
void Tick(ExecutionSerial completedSerial);
96-
97-
VkDeviceSize Size() const { return mTotalSize; }
98-
99-
private:
100-
std::map<ExecutionSerial, VkDeviceSize> mMemoryToDecrement;
101-
VkDeviceSize mTotalSize = 0;
102-
};
103-
10485
raw_ptr<Device> mDevice;
10586
const VkDeviceSize mMaxSizeForSuballocation;
10687
MemoryTypeSelector mMemoryTypeSelector;

0 commit comments

Comments
 (0)