D3D12: De-duplicate sampler heap allocations.

Allows bindgroups that use the same samplers to share
a descriptor heap allocation. This is particularly important
for sampler heaps which incur expensive pipeline flushes
due to the smaller size requiring more frequent switches.

The device dolls out entries to a sampler heap allocation cache.
When the BindGroup is created, it does a lookup and refs the
allocation. This ensures the cache does not grow unbounded
or needlessly store unused entires.

This change is a follow-up of de-coupling heaps.

BUG=dawn:155

Change-Id: I3ab6f1bdb13a40905cb990cd7a2139e73da30303
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20783
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/d3d12/BindGroupD3D12.h b/src/dawn_native/d3d12/BindGroupD3D12.h
index 05d67b4..54acb3d 100644
--- a/src/dawn_native/d3d12/BindGroupD3D12.h
+++ b/src/dawn_native/d3d12/BindGroupD3D12.h
@@ -24,7 +24,9 @@
 namespace dawn_native { namespace d3d12 {
 
     class Device;
+    class SamplerHeapCacheEntry;
     class ShaderVisibleDescriptorAllocator;
+    class StagingDescriptorAllocator;
 
     class BindGroup final : public BindGroupBase, public PlacementAllocated {
       public:
@@ -34,30 +36,23 @@
         BindGroup(Device* device,
                   const BindGroupDescriptor* descriptor,
                   uint32_t viewSizeIncrement,
-                  const CPUDescriptorHeapAllocation& viewAllocation,
-                  uint32_t samplerSizeIncrement,
-                  const CPUDescriptorHeapAllocation& samplerAllocation);
+                  const CPUDescriptorHeapAllocation& viewAllocation);
 
         // Returns true if the BindGroup was successfully populated.
         bool PopulateViews(ShaderVisibleDescriptorAllocator* viewAllocator);
-        bool PopulateSamplers(ShaderVisibleDescriptorAllocator* samplerAllocator);
+        bool PopulateSamplers(Device* device, ShaderVisibleDescriptorAllocator* samplerAllocator);
 
         D3D12_GPU_DESCRIPTOR_HANDLE GetBaseViewDescriptor() const;
         D3D12_GPU_DESCRIPTOR_HANDLE GetBaseSamplerDescriptor() const;
 
-      private:
-        bool Populate(ShaderVisibleDescriptorAllocator* allocator,
-                      uint32_t descriptorCount,
-                      D3D12_DESCRIPTOR_HEAP_TYPE heapType,
-                      const CPUDescriptorHeapAllocation& stagingAllocation,
-                      GPUDescriptorHeapAllocation* allocation);
+        void SetSamplerAllocationEntry(Ref<SamplerHeapCacheEntry> entry);
 
+      private:
         ~BindGroup() override;
 
-        GPUDescriptorHeapAllocation mGPUSamplerAllocation;
-        GPUDescriptorHeapAllocation mGPUViewAllocation;
+        Ref<SamplerHeapCacheEntry> mSamplerAllocationEntry;
 
-        CPUDescriptorHeapAllocation mCPUSamplerAllocation;
+        GPUDescriptorHeapAllocation mGPUViewAllocation;
         CPUDescriptorHeapAllocation mCPUViewAllocation;
     };
 }}  // namespace dawn_native::d3d12