Diligent Engine  v.2.4.g
VariableSizeGPUAllocationsManager.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019-2021 Diligent Graphics LLC
3  * Copyright 2015-2019 Egor Yusov
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * In no event and under no legal theory, whether in tort (including negligence),
18  * contract, or otherwise, unless required by applicable law (such as deliberate
19  * and grossly negligent acts) or agreed to in writing, shall any Contributor be
20  * liable for any damages, including any direct, indirect, special, incidental,
21  * or consequential damages of any character arising as a result of this License or
22  * out of the use or inability to use the software (including but not limited to damages
23  * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
24  * all other commercial damages or losses), even if such Contributor has been advised
25  * of the possibility of such damages.
26  */
27 
28 
29 // An GPU-tailored extension of the basic variable-size allocations manager
30 // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/
31 
32 #pragma once
33 
34 #include <deque>
36 
37 namespace Diligent
38 {
39 // Class extends basic variable-size memory block allocator by deferring deallocation
40 // of freed blocks untill the corresponding frame is completed
42 {
43 private:
44  struct StaleAllocationAttribs
45  {
46  OffsetType Offset;
47  OffsetType Size;
48  Uint64 FenceValue;
49  StaleAllocationAttribs(OffsetType _Offset, OffsetType _Size, Uint64 _FenceValue) :
50  Offset{_Offset}, Size{_Size}, FenceValue{_FenceValue}
51  {}
52  };
53 
54 public:
56  VariableSizeAllocationsManager{MaxSize, Allocator},
57  m_StaleAllocations{0, StaleAllocationAttribs(0, 0, 0), STD_ALLOCATOR_RAW_MEM(StaleAllocationAttribs, Allocator, "Allocator for deque<StaleAllocationAttribs>")}
58  {}
59 
61  {
62  VERIFY(m_StaleAllocations.empty(), "Not all stale allocations released");
63  VERIFY(m_StaleAllocationsSize == 0, "Not all stale allocations released");
64  }
65 
66  // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL)
68  VariableSizeAllocationsManager(std::move(rhs)),
69  m_StaleAllocations(std::move(rhs.m_StaleAllocations)),
70  m_StaleAllocationsSize(rhs.m_StaleAllocationsSize)
71  {
72  rhs.m_StaleAllocationsSize = 0;
73  }
74 
75  // clang-format off
79  // clang-format on
80 
82  {
83  Free(allocation.UnalignedOffset, allocation.Size, FenceValue);
85  }
86 
87  void Free(OffsetType Offset, OffsetType Size, Uint64 FenceValue)
88  {
89  // Do not release the block immediately, but add
90  // it to the queue instead
91  m_StaleAllocations.emplace_back(Offset, Size, FenceValue);
92  m_StaleAllocationsSize += Size;
93  }
94 
95  // Releases stale allocation from completed command lists
96  // The method takes the last known completed fence value N
97  // and releases all allocations whose associated fence value
98  // is at most N (n <= N)
99  void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue)
100  {
101  // Free all allocations from the beginning of the queue that belong to completed command lists
102  while (!m_StaleAllocations.empty() && m_StaleAllocations.front().FenceValue <= LastCompletedFenceValue)
103  {
104  auto& OldestAllocation = m_StaleAllocations.front();
105  VariableSizeAllocationsManager::Free(OldestAllocation.Offset, OldestAllocation.Size);
106  m_StaleAllocationsSize -= OldestAllocation.Size;
107  m_StaleAllocations.pop_front();
108  }
109  }
110 
111  size_t GetStaleAllocationsSize() const { return m_StaleAllocationsSize; }
112 
113 private:
114  std::deque<StaleAllocationAttribs, STDAllocatorRawMem<StaleAllocationAttribs>> m_StaleAllocations;
115  size_t m_StaleAllocationsSize = 0;
116 };
117 } // namespace Diligent
VariableSizeAllocationsManager.hpp
Diligent::VariableSizeGPUAllocationsManager::Free
void Free(VariableSizeAllocationsManager::Allocation &&allocation, Uint64 FenceValue)
Definition: VariableSizeGPUAllocationsManager.hpp:81
Diligent::VariableSizeGPUAllocationsManager::ReleaseStaleAllocations
void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue)
Definition: VariableSizeGPUAllocationsManager.hpp:99
Diligent::VariableSizeAllocationsManager
Definition: VariableSizeAllocationsManager.hpp:64
Diligent::Uint64
uint64_t Uint64
64-bit unsigned integer
Definition: BasicTypes.h:50
Diligent::VariableSizeAllocationsManager::Allocation
Definition: VariableSizeAllocationsManager.hpp:156
Diligent::VariableSizeGPUAllocationsManager::VariableSizeGPUAllocationsManager
VariableSizeGPUAllocationsManager(OffsetType MaxSize, IMemoryAllocator &Allocator)
Definition: VariableSizeGPUAllocationsManager.hpp:55
Diligent::VariableSizeGPUAllocationsManager::GetStaleAllocationsSize
size_t GetStaleAllocationsSize() const
Definition: VariableSizeGPUAllocationsManager.hpp:111
Diligent::VariableSizeGPUAllocationsManager::Free
void Free(OffsetType Offset, OffsetType Size, Uint64 FenceValue)
Definition: VariableSizeGPUAllocationsManager.hpp:87
Diligent::VariableSizeAllocationsManager::VariableSizeAllocationsManager
VariableSizeAllocationsManager(OffsetType MaxSize, IMemoryAllocator &Allocator)
Definition: VariableSizeAllocationsManager.hpp:101
Diligent::VariableSizeAllocationsManager::OffsetType
size_t OffsetType
Definition: VariableSizeAllocationsManager.hpp:67
Diligent::VariableSizeGPUAllocationsManager::VariableSizeGPUAllocationsManager
VariableSizeGPUAllocationsManager(VariableSizeGPUAllocationsManager &&rhs) noexcept
Definition: VariableSizeGPUAllocationsManager.hpp:67
Diligent::VariableSizeGPUAllocationsManager::operator=
VariableSizeGPUAllocationsManager & operator=(VariableSizeGPUAllocationsManager &&rhs)=delete
Diligent::VariableSizeGPUAllocationsManager
Definition: VariableSizeGPUAllocationsManager.hpp:41
Diligent::IMemoryAllocator
Base interface for a raw memory allocator.
Definition: MemoryAllocator.h:41
Diligent::VariableSizeGPUAllocationsManager::~VariableSizeGPUAllocationsManager
~VariableSizeGPUAllocationsManager()
Definition: VariableSizeGPUAllocationsManager.hpp:60
STD_ALLOCATOR_RAW_MEM
#define STD_ALLOCATOR_RAW_MEM(Type, Allocator, Description)
Definition: STDAllocator.hpp:179
VERIFY
#define VERIFY(...)
Definition: DebugUtilities.hpp:76
Diligent
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37
Diligent::VariableSizeAllocationsManager::Free
void Free(Allocation &&allocation)
Definition: VariableSizeAllocationsManager.hpp:251