• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef DAWNNATIVE_D3D12_SAMPLERHEAPCACHE_H_
16 #define DAWNNATIVE_D3D12_SAMPLERHEAPCACHE_H_
17 
18 #include "common/RefCounted.h"
19 #include "dawn_native/BindingInfo.h"
20 #include "dawn_native/d3d12/CPUDescriptorHeapAllocationD3D12.h"
21 #include "dawn_native/d3d12/GPUDescriptorHeapAllocationD3D12.h"
22 
23 #include <unordered_set>
24 
25 // |SamplerHeapCacheEntry| maintains a cache of sampler descriptor heap allocations.
26 // Each entry represents one or more sampler descriptors that co-exist in a CPU and
27 // GPU descriptor heap. The CPU-side allocation is deallocated once the final reference
28 // has been released while the GPU-side allocation is deallocated when the GPU is finished.
29 //
30 // The BindGroupLayout hands out these entries upon constructing the bindgroup. If the entry is not
31 // invalid, it will allocate and initialize so it may be reused by another bindgroup.
32 //
33 // The cache is primary needed for the GPU sampler heap, which is much smaller than the view heap
34 // and switches incur expensive pipeline flushes.
35 namespace dawn_native { namespace d3d12 {
36 
37     class BindGroup;
38     class Device;
39     class Sampler;
40     class SamplerHeapCache;
41     class StagingDescriptorAllocator;
42     class ShaderVisibleDescriptorAllocator;
43 
44     // Wraps sampler descriptor heap allocations in a cache.
45     class SamplerHeapCacheEntry : public RefCounted {
46       public:
47         SamplerHeapCacheEntry() = default;
48         SamplerHeapCacheEntry(std::vector<Sampler*> samplers);
49         SamplerHeapCacheEntry(SamplerHeapCache* cache,
50                               StagingDescriptorAllocator* allocator,
51                               std::vector<Sampler*> samplers,
52                               CPUDescriptorHeapAllocation allocation);
53         ~SamplerHeapCacheEntry() override;
54 
55         D3D12_GPU_DESCRIPTOR_HANDLE GetBaseDescriptor() const;
56 
57         std::vector<Sampler*>&& AcquireSamplers();
58 
59         bool Populate(Device* device, ShaderVisibleDescriptorAllocator* allocator);
60 
61         // Functors necessary for the unordered_map<SamplerHeapCacheEntry*>-based cache.
62         struct HashFunc {
63             size_t operator()(const SamplerHeapCacheEntry* entry) const;
64         };
65 
66         struct EqualityFunc {
67             bool operator()(const SamplerHeapCacheEntry* a, const SamplerHeapCacheEntry* b) const;
68         };
69 
70       private:
71         CPUDescriptorHeapAllocation mCPUAllocation;
72         GPUDescriptorHeapAllocation mGPUAllocation;
73 
74         // Storing raw pointer because the sampler object will be already hashed
75         // by the device and will already be unique.
76         std::vector<Sampler*> mSamplers;
77 
78         StagingDescriptorAllocator* mAllocator = nullptr;
79         SamplerHeapCache* mCache = nullptr;
80     };
81 
82     // Cache descriptor heap allocations so that we don't create duplicate ones for every
83     // BindGroup.
84     class SamplerHeapCache {
85       public:
86         SamplerHeapCache(Device* device);
87         ~SamplerHeapCache();
88 
89         ResultOrError<Ref<SamplerHeapCacheEntry>> GetOrCreate(
90             const BindGroup* group,
91             StagingDescriptorAllocator* samplerAllocator);
92 
93         void RemoveCacheEntry(SamplerHeapCacheEntry* entry);
94 
95       private:
96         Device* mDevice;
97 
98         using Cache = std::unordered_set<SamplerHeapCacheEntry*,
99                                          SamplerHeapCacheEntry::HashFunc,
100                                          SamplerHeapCacheEntry::EqualityFunc>;
101 
102         Cache mCache;
103     };
104 
105 }}  // namespace dawn_native::d3d12
106 
107 #endif  // DAWNNATIVE_D3D12_SAMPLERHEAPCACHE_H_
108