Diligent Engine API Reference
VariableSizeGPUAllocationsManager.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 
25 // An GPU-tailored extension of the basic variable-size allocations manager
26 // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/
27 
28 #pragma once
29 
30 #include <deque>
31 #include "VariableSizeAllocationsManager.h"
32 #include "STDAllocator.h"
33 
34 namespace Diligent
35 {
36  // Class extends basic variable-size memory block allocator by deferring deallocation
37  // of freed blocks untill the corresponding frame is completed
38  class VariableSizeGPUAllocationsManager : public VariableSizeAllocationsManager
39  {
40  private:
41  struct StaleAllocationAttribs
42  {
43  OffsetType Offset;
44  OffsetType Size;
45  Uint64 FenceValue;
46  StaleAllocationAttribs(OffsetType _Offset, OffsetType _Size, Uint64 _FenceValue) :
47  Offset(_Offset), Size(_Size), FenceValue(_FenceValue)
48  {}
49  };
50 
51  public:
52  VariableSizeGPUAllocationsManager(OffsetType MaxSize, IMemoryAllocator &Allocator) :
53  VariableSizeAllocationsManager(MaxSize, Allocator),
54  m_StaleAllocations(0, StaleAllocationAttribs(0,0,0), STD_ALLOCATOR_RAW_MEM(StaleAllocationAttribs, Allocator, "Allocator for deque<StaleAllocationAttribs>" ))
55  {}
56 
57  ~VariableSizeGPUAllocationsManager()
58  {
59  VERIFY(m_StaleAllocations.empty(), "Not all stale allocations released");
60  VERIFY(m_StaleAllocationsSize == 0, "Not all stale allocations released");
61  }
62 
63  // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL)
64  VariableSizeGPUAllocationsManager(VariableSizeGPUAllocationsManager&& rhs) :
65  VariableSizeAllocationsManager(std::move(rhs)),
66  m_StaleAllocations(std::move(rhs.m_StaleAllocations)),
67  m_StaleAllocationsSize(rhs.m_StaleAllocationsSize)
68  {
69  rhs.m_StaleAllocationsSize = 0;
70  }
71 
72  VariableSizeGPUAllocationsManager& operator = (VariableSizeGPUAllocationsManager&& rhs) = delete;
73  VariableSizeGPUAllocationsManager(const VariableSizeGPUAllocationsManager&) = delete;
74  VariableSizeGPUAllocationsManager& operator = (const VariableSizeGPUAllocationsManager&) = delete;
75 
76  void Free(OffsetType Offset, OffsetType Size, Uint64 FenceValue)
77  {
78  // Do not release the block immediately, but add
79  // it to the queue instead
80  m_StaleAllocations.emplace_back(Offset, Size, FenceValue);
81  m_StaleAllocationsSize += Size;
82  }
83 
84  // Releases stale allocation from completed command lists
85  // The method takes the last known completed fence value N
86  // and releases all allocations whose associated fence value
87  // is at most N (n <= N)
88  void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue)
89  {
90  // Free all allocations from the beginning of the queue that belong to completed command lists
91  while(!m_StaleAllocations.empty() && m_StaleAllocations.front().FenceValue <= LastCompletedFenceValue)
92  {
93  auto &OldestAllocation = m_StaleAllocations.front();
94  VariableSizeAllocationsManager::Free(OldestAllocation.Offset, OldestAllocation.Size);
95  m_StaleAllocationsSize -= OldestAllocation.Size;
96  m_StaleAllocations.pop_front();
97  }
98  }
99 
100  size_t GetStaleAllocationsSize()const { return m_StaleAllocationsSize; }
101 
102  private:
103  std::deque< StaleAllocationAttribs, STDAllocatorRawMem<StaleAllocationAttribs> > m_StaleAllocations;
104  size_t m_StaleAllocationsSize = 0;
105  };
106 }
Graphics engine namespace.
Definition: AdaptiveFixedBlockAllocator.h:30
Definition: AdvancedMath.h:316
uint64_t Uint64
64-bit unsigned integer
Definition: BasicTypes.h:38