Diligent Engine API Reference
DescriptorHeap.h
1 /* Copyright 2015-2018 Egor Yusov
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  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
12  *
13  * In no event and under no legal theory, whether in tort (including negligence),
14  * contract, or otherwise, unless required by applicable law (such as deliberate
15  * and grossly negligent acts) or agreed to in writing, shall any Contributor be
16  * liable for any damages, including any direct, indirect, special, incidental,
17  * or consequential damages of any character arising as a result of this License or
18  * out of the use or inability to use the software (including but not limited to damages
19  * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
20  * all other commercial damages or losses), even if such Contributor has been advised
21  * of the possibility of such damages.
22  */
23 
24 // Descriptor heap management utilities.
25 // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-descriptor-heaps/ for details
26 
27 #pragma once
28 
29 #include <mutex>
30 #include <vector>
31 #include <queue>
32 #include <string>
33 #include <set>
34 #include "ObjectBase.h"
35 #include "VariableSizeGPUAllocationsManager.h"
36 
37 namespace Diligent
38 {
39 
40 class DescriptorHeapAllocation;
41 class DescriptorHeapAllocationManager;
42 class RenderDeviceD3D12Impl;
43 
44 class IDescriptorAllocator
45 {
46 public:
47  // Allocate Count descriptors
48  virtual DescriptorHeapAllocation Allocate( uint32_t Count ) = 0;
49  virtual void Free(DescriptorHeapAllocation&& Allocation) = 0;
50  virtual Uint32 GetDescriptorSize()const = 0;
51 };
52 
53 
54 // The class represents descriptor heap allocation (continuous descriptor range in a descriptor heap)
55 //
56 // m_FirstCpuHandle
57 // |
58 // | ~ ~ ~ ~ ~ X X X X X X X ~ ~ ~ ~ ~ ~ | D3D12 Descriptor Heap
59 // |
60 // m_FirstGpuHandle
61 //
62 class DescriptorHeapAllocation
63 {
64 public:
65  // Creates null allocation
66  DescriptorHeapAllocation() :
67  m_NumHandles(1), // One null descriptor handle
68  m_pDescriptorHeap(nullptr),
69  m_DescriptorSize(0)
70  {
71  m_FirstCpuHandle.ptr = 0;
72  m_FirstGpuHandle.ptr = 0;
73  }
74 
75  // Initializes non-null allocation
76  DescriptorHeapAllocation( IDescriptorAllocator *pAllocator,
77  ID3D12DescriptorHeap *pHeap,
78  D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle,
79  D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle,
80  Uint32 NHandles,
81  Uint16 AllocationManagerId = static_cast<Uint16>(-1) ) :
82  m_FirstCpuHandle(CpuHandle),
83  m_FirstGpuHandle(GpuHandle),
84  m_pAllocator(pAllocator),
85  m_NumHandles(NHandles),
86  m_pDescriptorHeap(pHeap),
87  m_AllocationManagerId(AllocationManagerId)
88  {
89  VERIFY_EXPR(m_pAllocator != nullptr && m_pDescriptorHeap != nullptr);
90  auto DescriptorSize = m_pAllocator->GetDescriptorSize();
91  VERIFY(DescriptorSize < std::numeric_limits<Uint16>::max(), "DescriptorSize exceeds allowed limit");
92  m_DescriptorSize = static_cast<Uint16>( DescriptorSize );
93  }
94 
95  // Move constructor (copy is not allowed)
96  DescriptorHeapAllocation(DescriptorHeapAllocation &&Allocation) :
97  m_FirstCpuHandle(Allocation.m_FirstCpuHandle),
98  m_FirstGpuHandle(Allocation.m_FirstGpuHandle),
99  m_NumHandles(Allocation.m_NumHandles),
100  m_pAllocator(std::move(Allocation.m_pAllocator)),
101  m_AllocationManagerId(std::move(Allocation.m_AllocationManagerId)),
102  m_pDescriptorHeap(std::move(Allocation.m_pDescriptorHeap) ),
103  m_DescriptorSize(std::move(Allocation.m_DescriptorSize) )
104  {
105  Allocation.m_pAllocator = nullptr;
106  Allocation.m_FirstCpuHandle.ptr = 0;
107  Allocation.m_FirstGpuHandle.ptr = 0;
108  Allocation.m_NumHandles = 0;
109  Allocation.m_pDescriptorHeap = nullptr;
110  Allocation.m_DescriptorSize = 0;
111  Allocation.m_AllocationManagerId = static_cast<Uint16>(-1);
112  }
113 
114  // Move assignment (assignment is not allowed)
115  DescriptorHeapAllocation& operator = (DescriptorHeapAllocation &&Allocation)
116  {
117  m_FirstCpuHandle = Allocation.m_FirstCpuHandle;
118  m_FirstGpuHandle = Allocation.m_FirstGpuHandle;
119  m_NumHandles = Allocation.m_NumHandles;
120  m_pAllocator = std::move(Allocation.m_pAllocator);
121  m_AllocationManagerId = std::move(Allocation.m_AllocationManagerId);
122  m_pDescriptorHeap = std::move(Allocation.m_pDescriptorHeap);
123  m_DescriptorSize = std::move(Allocation.m_DescriptorSize);
124 
125  Allocation.m_FirstCpuHandle.ptr = 0;
126  Allocation.m_FirstGpuHandle.ptr = 0;
127  Allocation.m_NumHandles = 0;
128  Allocation.m_pAllocator = nullptr;
129  Allocation.m_pDescriptorHeap = nullptr;
130  Allocation.m_DescriptorSize = 0;
131  Allocation.m_AllocationManagerId = static_cast<Uint16>(-1);
132 
133  return *this;
134  }
135 
136  // Destructor automatically releases this allocation through the allocator
137  ~DescriptorHeapAllocation()
138  {
139  if(!IsNull() && m_pAllocator)
140  m_pAllocator->Free(std::move(*this));
141  // Allocation must have been disposed by the allocator
142  VERIFY(IsNull(), "Non-null descriptor is being destroyed");
143  }
144 
145  // Returns CPU descriptor handle at the specified offset
146  D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Uint32 Offset = 0) const
147  {
148  VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles);
149 
150  D3D12_CPU_DESCRIPTOR_HANDLE CPUHandle = m_FirstCpuHandle;
151  if (Offset != 0)
152  {
153  CPUHandle.ptr += m_DescriptorSize * Offset;
154  }
155  return CPUHandle;
156  }
157 
158  // Returns GPU descriptor handle at the specified offset
159  D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Uint32 Offset = 0) const
160  {
161  VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles);
162  D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle = m_FirstGpuHandle;
163  if (Offset != 0)
164  {
165  GPUHandle.ptr += m_DescriptorSize * Offset;
166  }
167  return GPUHandle;
168  }
169 
170  // Returns pointer to D3D12 descriptor heap that contains this allocation
171  ID3D12DescriptorHeap *GetDescriptorHeap(){return m_pDescriptorHeap;}
172 
173  size_t GetNumHandles()const{return m_NumHandles;}
174 
175  bool IsNull() const { return m_FirstCpuHandle.ptr == 0; }
176  bool IsShaderVisible() const { return m_FirstGpuHandle.ptr != 0; }
177  size_t GetAllocationManagerId(){return m_AllocationManagerId;}
178  UINT GetDescriptorSize()const{return m_DescriptorSize;}
179 
180 private:
181  // No copies, only moves are allowed
182  DescriptorHeapAllocation(const DescriptorHeapAllocation&) = delete;
183  DescriptorHeapAllocation& operator= (const DescriptorHeapAllocation&) = delete;
184 
185  // First CPU descriptor handle in this allocation
186  D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCpuHandle = {0};
187 
188  // First GPU descriptor handle in this allocation
189  D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGpuHandle = {0};
190 
191  // Keep strong reference to the parent heap to make sure it is alive while allocation is alive - TOO EXPENSIVE
192  //RefCntAutoPtr<IDescriptorAllocator> m_pAllocator;
193 
194  // Pointer to the descriptor heap allocator that created this allocation
195  IDescriptorAllocator* m_pAllocator = nullptr;
196 
197  // Pointer to the D3D12 descriptor heap that contains descriptors in this allocation
198  ID3D12DescriptorHeap* m_pDescriptorHeap = nullptr;
199 
200  // Number of descriptors in the allocation
201  Uint32 m_NumHandles = 0;
202 
203  // Allocation manager ID. One allocator may support several
204  // allocation managers. This field is required to identify
205  // the manager within the allocator that was used to create
206  // this allocation
207  Uint16 m_AllocationManagerId = static_cast<Uint16>(-1);
208 
209  // Descriptor size
210  Uint16 m_DescriptorSize = 0;
211 };
212 
213 
214 // The class performs suballocations within one D3D12 descriptor heap.
215 // It uses VariableSizeGPUAllocationsManager to manage free space in the heap
216 //
217 // | X X X X O O O X X O O X O O O O | D3D12 descriptor heap
218 //
219 // X - used descriptor
220 // O - available descriptor
221 //
222 class DescriptorHeapAllocationManager
223 {
224 public:
225  // Creates a new D3D12 descriptor heap
226  DescriptorHeapAllocationManager(IMemoryAllocator &Allocator,
227  RenderDeviceD3D12Impl *pDeviceD3D12Impl,
228  IDescriptorAllocator *pParentAllocator,
229  size_t ThisManagerId,
230  const D3D12_DESCRIPTOR_HEAP_DESC &HeapDesc);
231 
232  // Uses subrange of descriptors in the existing D3D12 descriptor heap
233  // that starts at offset FirstDescriptor and uses NumDescriptors descriptors
234  DescriptorHeapAllocationManager(IMemoryAllocator &Allocator,
235  RenderDeviceD3D12Impl *pDeviceD3D12Impl,
236  IDescriptorAllocator *pParentAllocator,
237  size_t ThisManagerId,
238  ID3D12DescriptorHeap *pd3d12DescriptorHeap,
239  Uint32 FirstDescriptor,
240  Uint32 NumDescriptors);
241 
242 
243  // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL)
244  DescriptorHeapAllocationManager(DescriptorHeapAllocationManager&& rhs) :
245  m_FreeBlockManager(std::move(rhs.m_FreeBlockManager)),
246  m_HeapDesc(rhs.m_HeapDesc),
247  m_pd3d12DescriptorHeap(std::move(rhs.m_pd3d12DescriptorHeap)),
248  m_FirstCPUHandle(rhs.m_FirstCPUHandle),
249  m_FirstGPUHandle(rhs.m_FirstGPUHandle),
250  m_DescriptorSize(rhs.m_DescriptorSize),
251  m_NumDescriptorsInAllocation(rhs.m_NumDescriptorsInAllocation),
252  // Mutex is not movable
253  //m_AllocationMutex(std::move(rhs.m_AllocationMutex))
254  m_pDeviceD3D12Impl(rhs.m_pDeviceD3D12Impl),
255  m_pParentAllocator(rhs.m_pParentAllocator),
256  m_ThisManagerId(rhs.m_ThisManagerId)
257  {
258  rhs.m_FirstCPUHandle.ptr = 0;
259  rhs.m_FirstGPUHandle.ptr = 0;
260  rhs.m_DescriptorSize = 0;
261  rhs.m_NumDescriptorsInAllocation = 0;
262  rhs.m_HeapDesc.NumDescriptors = 0;
263  rhs.m_pDeviceD3D12Impl = nullptr;
264  rhs.m_pParentAllocator = nullptr;
265  rhs.m_ThisManagerId = static_cast<size_t>(-1);
266  }
267 
268  // No copies or move-assignments
269  DescriptorHeapAllocationManager& operator = (DescriptorHeapAllocationManager&& rhs) = delete;
270  DescriptorHeapAllocationManager(const DescriptorHeapAllocationManager&) = delete;
271  DescriptorHeapAllocationManager& operator = (const DescriptorHeapAllocationManager&) = delete;
272 
273  ~DescriptorHeapAllocationManager();
274 
275  // Allocates Count descriptors
276  DescriptorHeapAllocation Allocate( uint32_t Count );
277 
278  // Releases descriptor heap allocation.
279  // Note that the allocation is not released immediately, but
280  // added to the release queue in the allocations manager
281  void Free(DescriptorHeapAllocation&& Allocation);
282 
283  // Releases all stale allocation used by completed command lists
284  // The method takes the last known completed fence value N
285  // and releases all allocations whose associated fence value n <= N
286  void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue);
287 
288  size_t GetNumAvailableDescriptors()const{return m_FreeBlockManager.GetFreeSize();}
289  size_t GetNumStaleDescriptors()const { return m_FreeBlockManager.GetStaleAllocationsSize(); }
290  Uint32 GetMaxDescriptors()const { return m_NumDescriptorsInAllocation; }
291 
292 private:
293  // Allocations manager used to handle descriptor allocations within the heap
294  VariableSizeGPUAllocationsManager m_FreeBlockManager;
295 
296  // Heap description
297  D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc;
298 
299  // Strong reference to D3D12 descriptor heap object
300  CComPtr<ID3D12DescriptorHeap> m_pd3d12DescriptorHeap;
301 
302  // First CPU descriptor handle in the available descriptor range
303  D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCPUHandle = {0};
304 
305  // First GPU descriptor handle in the available descriptor range
306  D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGPUHandle = {0};
307 
308  UINT m_DescriptorSize = 0;
309 
310  // Number of descriptors in the allocation.
311  // If this manager was initialized as a subrange in the existing heap,
312  // this value may be different from m_HeapDesc.NumDescriptors
313  Uint32 m_NumDescriptorsInAllocation = 0;
314 
315  std::mutex m_AllocationMutex;
316  RenderDeviceD3D12Impl *m_pDeviceD3D12Impl = nullptr;
317  IDescriptorAllocator *m_pParentAllocator = nullptr;
318 
319  // External ID assigned to this descriptor allocations manager
320  size_t m_ThisManagerId = static_cast<size_t>(-1);
321 };
322 
323 // CPU descriptor heap is intended to provide storage for resource view descriptor handles
324 // It contains a pool of DescriptorHeapAllocationManager object instances, where every instance manages
325 // its own CPU-only D3D12 descriptor heap:
326 //
327 // m_HeapPool[0] m_HeapPool[1] m_HeapPool[2]
328 // | X X X X X X X X |, | X X X O O X X O |, | X O O O O O O O |
329 //
330 // X - used descriptor m_AvailableHeaps = {1,2}
331 // O - available descriptor
332 //
333 // Allocation routine goes through the list of managers that have available descriptors and tries to process
334 // the request using every manager. If there are no available managers or no manager was able to handle the request,
335 // the function creates a new descriptor heap manager and lets it handle the request
336 //
337 // Render device contains four CPUDescriptorHeap object instances (one for each D3D12 heap type). The heaps are accessed
338 // when a texture or a buffer view is created.
339 //
340 class CPUDescriptorHeap : public IDescriptorAllocator
341 {
342 public:
343  // Initializes the heap
344  CPUDescriptorHeap(IMemoryAllocator &Allocator,
345  RenderDeviceD3D12Impl *pDeviceD3D12Impl,
346  Uint32 NumDescriptorsInHeap,
347  D3D12_DESCRIPTOR_HEAP_TYPE Type,
348  D3D12_DESCRIPTOR_HEAP_FLAGS Flags);
349 
350  CPUDescriptorHeap(const CPUDescriptorHeap&) = delete;
351  CPUDescriptorHeap(CPUDescriptorHeap&&) = delete;
352  CPUDescriptorHeap& operator = (const CPUDescriptorHeap&) = delete;
353  CPUDescriptorHeap& operator = (CPUDescriptorHeap&&) = delete;
354 
355  ~CPUDescriptorHeap();
356 
357  virtual DescriptorHeapAllocation Allocate( uint32_t Count )override;
358  virtual void Free(DescriptorHeapAllocation&& Allocation)override;
359  virtual Uint32 GetDescriptorSize()const override{return m_DescriptorSize;}
360 
361  // Releases all stale allocation used by completed command lists
362  // The method takes the last known completed fence value N
363  // and releases all allocations whose associated fence value n <= N
364  void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue);
365 
366 protected:
367 
368  // Pool of descriptor heap managers
369  std::vector<DescriptorHeapAllocationManager, STDAllocatorRawMem<DescriptorHeapAllocationManager> > m_HeapPool;
370  // Indices of available descriptor heap managers
371  std::set<size_t, std::less<size_t>, STDAllocatorRawMem<size_t> > m_AvailableHeaps;
372  IMemoryAllocator &m_MemAllocator;
373 
374  std::mutex m_AllocationMutex;
375 
376  D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc;
377  RenderDeviceD3D12Impl *m_pDeviceD3D12Impl;
378  UINT m_DescriptorSize;
379 
380  // Maximum heap size during the application lifetime - for statistic purposes
381  Uint32 m_MaxHeapSize = 0;
382  Uint32 m_MaxStaleSize = 0;
383  Uint32 m_CurrentSize = 0; // This size does not count stale allocation
384 };
385 
386 // GPU descriptor heap provides storage for shader-visible descriptors
387 // The heap contains single D3D12 descriptor heap that is broken into two parts.
388 // The first part stores static and mutable resource descriptor handles.
389 // The second part is intended to provide temporary storage for dynamic resources
390 // Space for dynamic resources is allocated in chunks, and then descriptors are suballocated within every
391 // chunk. DynamicSuballocationsManager facilitates this process
392 //
393 //
394 // static and mutable handles || dynamic space
395 // || chunk 0 chunk 1 chunk 2 unused
396 // | X O O X X O X O O O O X X X X O || | X X X O | | X X O O | | O O O O | O O O O ||
397 // | |
398 // suballocation suballocation
399 // within chunk 0 within chunk 1
400 //
401 // Render device contains two GPUDescriptorHeap instances (CBV_SRV_UAV and SAMPLER). The heaps
402 // are used to allocate GPU-visible descriptors for shader resource binding objects. The heaps
403 // are also used by the command contexts (through DynamicSuballocationsManager to allocated dynamic descriptors)
404 //
405 // _______________________________________________________________________________________________________________________________
406 // | Render Device |
407 // | |
408 // | m_CPUDescriptorHeaps[CBV_SRV_UAV] | X X X X X X X X |, | X X X X X X X X |, | X O O X O O O O | |
409 // | m_CPUDescriptorHeaps[SAMPLER] | X X X X O O O X |, | X O O X O O O O | |
410 // | m_CPUDescriptorHeaps[RTV] | X X X O O O O O |, | O O O O O O O O | |
411 // | m_CPUDescriptorHeaps[DSV] | X X X O X O X O | |
412 // | ctx1 ctx2 |
413 // | m_GPUDescriptorHeaps[CBV_SRV_UAV] | X O O X X O X O O O O X X X X O || | X X X O | | X X O O | | O O O O | O O O O || |
414 // | m_GPUDescriptorHeaps[SAMPLER] | X X O O X O X X X O O X O O O O || | X X O O | | X O O O | | O O O O | O O O O || |
415 // | |
416 // |_______________________________________________________________________________________________________________________________|
417 //
418 // ________________________________________________ ________________________________________________
419 // |Device Context 1 | |Device Context 2 |
420 // | | | |
421 // | m_DynamicGPUDescriptorAllocator[CBV_SRV_UAV] | | m_DynamicGPUDescriptorAllocator[CBV_SRV_UAV] |
422 // | m_DynamicGPUDescriptorAllocator[SAMPLER] | | m_DynamicGPUDescriptorAllocator[SAMPLER] |
423 // |________________________________________________| |________________________________________________|
424 //
425 class GPUDescriptorHeap : public IDescriptorAllocator
426 {
427 public:
428  GPUDescriptorHeap(IMemoryAllocator &Allocator,
429  RenderDeviceD3D12Impl *pDevice,
430  Uint32 NumDescriptorsInHeap,
431  Uint32 NumDynamicDescriptors,
432  D3D12_DESCRIPTOR_HEAP_TYPE Type,
433  D3D12_DESCRIPTOR_HEAP_FLAGS Flags);
434 
435  GPUDescriptorHeap(const GPUDescriptorHeap&) = delete;
436  GPUDescriptorHeap(GPUDescriptorHeap&&) = delete;
437  GPUDescriptorHeap& operator = (const GPUDescriptorHeap&) = delete;
438  GPUDescriptorHeap& operator = (GPUDescriptorHeap&&) = delete;
439 
440  ~GPUDescriptorHeap();
441 
442  virtual DescriptorHeapAllocation Allocate( uint32_t Count )override;
443  virtual void Free(DescriptorHeapAllocation&& Allocation)override;
444  virtual Uint32 GetDescriptorSize()const override{return m_DescriptorSize;}
445 
446  DescriptorHeapAllocation AllocateDynamic( uint32_t Count );
447 
448  // Releases all stale allocation used by completed command lists
449  // The method takes the last known completed fence value N
450  // and releases all allocations whose associated fence value n <= N
451  void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue);
452 
453  const D3D12_DESCRIPTOR_HEAP_DESC &GetHeapDesc()const{return m_HeapDesc;}
454  Uint32 GetMaxStaticDescriptors()const { return m_HeapAllocationManager.GetMaxDescriptors(); }
455  Uint32 GetMaxDynamicDescriptors()const { return m_DynamicAllocationsManager.GetMaxDescriptors(); }
456 
457 protected:
458 
459  D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc;
460  CComPtr<ID3D12DescriptorHeap> m_pd3d12DescriptorHeap;
461 
462  UINT m_DescriptorSize = 0;
463 
464  std::mutex m_AllocMutex, m_DynAllocMutex;
465  // Allocation manager for static/mutable part
466  DescriptorHeapAllocationManager m_HeapAllocationManager;
467 
468  // Allocation manager for dynamic part
469  DescriptorHeapAllocationManager m_DynamicAllocationsManager;
470 
471  RenderDeviceD3D12Impl *m_pDeviceD3D12;
472  Uint32 m_CurrentSize = 0;
473  // Maximum static/mutable part size during the application lifetime - for statistic purposes
474  Uint32 m_MaxHeapSize = 0;
475  Uint32 m_MaxStaleSize = 0;
476  Uint32 m_CurrentDynamicSize = 0;
477  // Maximum dynamic part size during the application lifetime - for statistic purposes
478  Uint32 m_MaxDynamicSize = 0;
479  Uint32 m_MaxDynamicStaleSize = 0;
480 };
481 
482 
483 // The class facilitates allocation of dynamic descriptor handles. It requests a chunk of heap
484 // from the master GPU descriptor heap and then performs linear suballocation within the chunk
485 // At the end of the frame all allocations are disposed.
486 
487 // static and mutable handles || dynamic space
488 // || chunk 0 chunk 2
489 // | || | X X X O | | O O O O | || GPU Descriptor Heap
490 // | |
491 // m_Suballocations[0] m_Suballocations[1]
492 //
493 class DynamicSuballocationsManager : public IDescriptorAllocator
494 {
495 public:
496  DynamicSuballocationsManager(IMemoryAllocator &Allocator, GPUDescriptorHeap& ParentGPUHeap, Uint32 DynamicChunkSize);
497 
498  DynamicSuballocationsManager(const DynamicSuballocationsManager&) = delete;
499  DynamicSuballocationsManager(DynamicSuballocationsManager&&) = delete;
500  DynamicSuballocationsManager& operator = (const DynamicSuballocationsManager&) = delete;
501  DynamicSuballocationsManager& operator = (DynamicSuballocationsManager&&) = delete;
502 
503  void DiscardAllocations(Uint64 /*FenceValue*/);
504 
505  virtual DescriptorHeapAllocation Allocate( Uint32 Count )override;
506  virtual void Free(DescriptorHeapAllocation&& Allocation)override;
507 
508  virtual Uint32 GetDescriptorSize()const override{return m_ParentGPUHeap.GetDescriptorSize();}
509 
510 private:
511  // List of chunks allocated from the master GPU descriptor heap. All chunks are disposed at the end
512  // of the frame
513  std::vector<DescriptorHeapAllocation, STDAllocatorRawMem<DescriptorHeapAllocation> > m_Suballocations;
514 
515  Uint32 m_CurrentSuballocationOffset = 0;
516  Uint32 m_DynamicChunkSize = 0;
517 
518  // Parent GPU descriptor heap that is used to allocate chunks
519  GPUDescriptorHeap &m_ParentGPUHeap;
520 };
521 
522 }
Namespace for the OpenGL implementation of the graphics engine.
Definition: BufferD3D11Impl.h:34
Definition: AdvancedMath.h:316