Track ShaderVisibleDescriptorHeap Upon Allocation

Fixes bug where a newly allocated ShaderVisibleDescriptorHeap would be
untracked in the residency LRU upon allocation, causing Dawn's residency
manager to become out of sync with D3D12's internal residency refcount
by calling MakeResident once more than needed.

Bug: dawn:193
Change-Id: I47804471b41df476db989634e50bded6006e05aa
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23125
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/d3d12/ResidencyManagerD3D12.cpp b/src/dawn_native/d3d12/ResidencyManagerD3D12.cpp
index eec7160..053a169 100644
--- a/src/dawn_native/d3d12/ResidencyManagerD3D12.cpp
+++ b/src/dawn_native/d3d12/ResidencyManagerD3D12.cpp
@@ -333,7 +333,10 @@
     }
 
     // Inserts a heap at the bottom of the LRU. The passed heap must be resident or scheduled to
-    // become resident within the current serial.
+    // become resident within the current serial. Failing to call this function when an allocation
+    // is implicitly made resident will cause the residency manager to view the allocation as
+    // non-resident and call MakeResident - which will make D3D12's internal residency refcount on
+    // the allocation out of sync with Dawn.
     void ResidencyManager::TrackResidentAllocation(Pageable* pageable) {
         if (!mResidencyManagementEnabled) {
             return;
diff --git a/src/dawn_native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp b/src/dawn_native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
index 258d5c3..9039d8a 100644
--- a/src/dawn_native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
+++ b/src/dawn_native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
@@ -152,6 +152,9 @@
                                         "ID3D12Device::CreateDescriptorHeap"));
             descriptorHeap = std::make_unique<ShaderVisibleDescriptorHeap>(
                 std::move(d3d12DescriptorHeap), kSize);
+            // We must track the allocation in the LRU when it is created, otherwise the residency
+            // manager will see the allocation as non-resident in the later call to LockAllocation.
+            mDevice->GetResidencyManager()->TrackResidentAllocation(descriptorHeap.get());
         }
 
         DAWN_TRY(mDevice->GetResidencyManager()->LockAllocation(descriptorHeap.get()));