Diligent Engine  v.2.4.g
D3D12DynamicHeap.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 #pragma once
29 
30 #include <mutex>
31 #include <map>
32 #include <deque>
33 #include <atomic>
34 
35 namespace Diligent
36 {
37 
38 class RenderDeviceD3D12Impl;
39 
41 {
42  D3D12DynamicAllocation() noexcept {}
43  D3D12DynamicAllocation(ID3D12Resource* pBuff,
44  Uint64 _Offset,
45  Uint64 _Size,
46  void* _CPUAddress,
47  D3D12_GPU_VIRTUAL_ADDRESS _GPUAddress
48 #ifdef DILIGENT_DEVELOPMENT
49  ,
50  Uint64 _DvpCtxFrameNumber
51 #endif
52  ) noexcept :
53  // clang-format off
54  pBuffer {pBuff },
55  Offset {_Offset },
56  Size {_Size },
57  CPUAddress {_CPUAddress },
58  GPUAddress {_GPUAddress }
59 #ifdef DILIGENT_DEVELOPMENT
60  , DvpCtxFrameNumber(_DvpCtxFrameNumber)
61 #endif
62  // clang-format on
63  {}
64 
65  ID3D12Resource* pBuffer = nullptr; // The D3D buffer associated with this memory.
66  Uint64 Offset = 0; // Offset from start of buffer resource
67  Uint64 Size = 0; // Reserved size of this allocation
68  void* CPUAddress = nullptr; // The CPU-writeable address
69  D3D12_GPU_VIRTUAL_ADDRESS GPUAddress = 0; // The GPU-visible address
70 #ifdef DILIGENT_DEVELOPMENT
71  Uint64 DvpCtxFrameNumber = static_cast<Uint64>(-1);
72 #endif
73 };
74 
75 
77 {
78 public:
79  D3D12DynamicPage(ID3D12Device* pd3d12Device, Uint64 Size);
80 
81  // clang-format off
82  D3D12DynamicPage (const D3D12DynamicPage&) = delete;
83  D3D12DynamicPage ( D3D12DynamicPage&&) = default;
86  // clang-format on
87 
88  void* GetCPUAddress(Uint64 Offset)
89  {
90  VERIFY_EXPR(m_pd3d12Buffer);
91  VERIFY(Offset < GetSize(), "Offset (", Offset, ") exceeds buffer size (", GetSize(), ")");
92  return reinterpret_cast<Uint8*>(m_CPUVirtualAddress) + Offset;
93  }
94 
95  D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint64 Offset)
96  {
97  VERIFY_EXPR(m_pd3d12Buffer);
98  VERIFY(Offset < GetSize(), "Offset (", Offset, ") exceeds buffer size (", GetSize(), ")");
99  return m_GPUVirtualAddress + Offset;
100  }
101 
102  ID3D12Resource* GetD3D12Buffer()
103  {
104  return m_pd3d12Buffer;
105  }
106 
107  Uint64 GetSize() const
108  {
109  VERIFY_EXPR(m_pd3d12Buffer);
110  return m_pd3d12Buffer->GetDesc().Width;
111  }
112 
113  bool IsValid() const { return m_pd3d12Buffer != nullptr; }
114 
115 private:
116  CComPtr<ID3D12Resource> m_pd3d12Buffer;
117  void* m_CPUVirtualAddress = nullptr; // The CPU-writeable address
118  D3D12_GPU_VIRTUAL_ADDRESS m_GPUVirtualAddress = 0; // The GPU-visible address
119 };
120 
121 
123 {
124 public:
126  RenderDeviceD3D12Impl& DeviceD3D12Impl,
127  Uint32 NumPagesToReserve,
128  Uint64 PageSize);
130 
131  // clang-format off
136  // clang-format on
137 
138  void ReleasePages(std::vector<D3D12DynamicPage>& Pages, Uint64 QueueMask);
139 
140  void Destroy();
141 
142  D3D12DynamicPage AllocatePage(Uint64 SizeInBytes);
143 
144 #ifdef DILIGENT_DEVELOPMENT
145  int32_t GetAllocatedPageCounter() const
146  {
147  return m_AllocatedPageCounter;
148  }
149 #endif
150 
151 private:
152  RenderDeviceD3D12Impl& m_DeviceD3D12Impl;
153 
154  std::mutex m_AvailablePagesMtx;
155  using AvailablePagesMapElemType = std::pair<const Uint64, D3D12DynamicPage>;
156  std::multimap<Uint64, D3D12DynamicPage, std::less<Uint64>, STDAllocatorRawMem<AvailablePagesMapElemType>> m_AvailablePages;
157 
158 #ifdef DILIGENT_DEVELOPMENT
159  std::atomic_int32_t m_AllocatedPageCounter = 0;
160 #endif
161 };
162 
163 
165 {
166 public:
167  D3D12DynamicHeap(D3D12DynamicMemoryManager& DynamicMemMgr, std::string HeapName, Uint64 PageSize) :
168  m_GlobalDynamicMemMgr{DynamicMemMgr},
169  m_HeapName{std::move(HeapName)},
170  m_PageSize{PageSize}
171  {}
172 
173  // clang-format off
174  D3D12DynamicHeap (const D3D12DynamicHeap&) = delete;
175  D3D12DynamicHeap (D3D12DynamicHeap&&) = delete;
176  D3D12DynamicHeap& operator= (const D3D12DynamicHeap&) = delete;
178  // clang-format on
179 
181 
182  D3D12DynamicAllocation Allocate(Uint64 SizeInBytes, Uint64 Alignment, Uint64 DvpCtxFrameNumber);
183  void ReleaseAllocatedPages(Uint64 QueueMask);
184 
185  static constexpr Uint64 InvalidOffset = static_cast<Uint64>(-1);
186 
187  size_t GetAllocatedPagesCount() const { return m_AllocatedPages.size(); }
188 
189 private:
190  D3D12DynamicMemoryManager& m_GlobalDynamicMemMgr;
191  const std::string m_HeapName;
192 
193  std::vector<D3D12DynamicPage> m_AllocatedPages;
194 
195  const Uint64 m_PageSize;
196 
197  Uint64 m_CurrOffset = InvalidOffset;
198  Uint64 m_AvailableSize = 0;
199 
200  Uint64 m_CurrAllocatedSize = 0;
201  Uint64 m_CurrUsedSize = 0;
202  Uint64 m_CurrAlignedSize = 0;
203  Uint64 m_PeakAllocatedSize = 0;
204  Uint64 m_PeakUsedSize = 0;
205  Uint64 m_PeakAlignedSize = 0;
206 };
207 
208 } // namespace Diligent
Diligent::D3D12DynamicMemoryManager::operator=
D3D12DynamicMemoryManager & operator=(const D3D12DynamicMemoryManager &)=delete
Diligent::D3D12DynamicAllocation::D3D12DynamicAllocation
D3D12DynamicAllocation(ID3D12Resource *pBuff, Uint64 _Offset, Uint64 _Size, void *_CPUAddress, D3D12_GPU_VIRTUAL_ADDRESS _GPUAddress) noexcept
Definition: D3D12DynamicHeap.hpp:43
Diligent::D3D12DynamicMemoryManager::~D3D12DynamicMemoryManager
~D3D12DynamicMemoryManager()
Definition: D3D12DynamicHeap.cpp:172
Diligent::Uint64
uint64_t Uint64
64-bit unsigned integer
Definition: BasicTypes.h:50
Diligent::D3D12DynamicPage::GetGPUAddress
D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint64 Offset)
Definition: D3D12DynamicHeap.hpp:95
Diligent::D3D12DynamicHeap
Definition: D3D12DynamicHeap.hpp:164
Diligent::D3D12DynamicPage::IsValid
bool IsValid() const
Definition: D3D12DynamicHeap.hpp:113
Diligent::D3D12DynamicPage::operator=
D3D12DynamicPage & operator=(const D3D12DynamicPage &)=delete
Diligent::D3D12DynamicMemoryManager
Definition: D3D12DynamicHeap.hpp:122
Diligent::STDAllocator
Definition: STDAllocator.hpp:53
Diligent::D3D12DynamicPage
Definition: D3D12DynamicHeap.hpp:76
Diligent::D3D12DynamicHeap::GetAllocatedPagesCount
size_t GetAllocatedPagesCount() const
Definition: D3D12DynamicHeap.hpp:187
Diligent::RenderDeviceD3D12Impl
Render device implementation in Direct3D12 backend.
Definition: RenderDeviceD3D12Impl.hpp:70
Diligent::D3D12DynamicHeap::operator=
D3D12DynamicHeap & operator=(const D3D12DynamicHeap &)=delete
Diligent::D3D12DynamicMemoryManager::AllocatePage
D3D12DynamicPage AllocatePage(Uint64 SizeInBytes)
Definition: D3D12DynamicHeap.cpp:93
Diligent::D3D12DynamicPage::GetD3D12Buffer
ID3D12Resource * GetD3D12Buffer()
Definition: D3D12DynamicHeap.hpp:102
Diligent::D3D12DynamicHeap::InvalidOffset
static constexpr Uint64 InvalidOffset
Definition: D3D12DynamicHeap.hpp:185
Diligent::D3D12DynamicMemoryManager::D3D12DynamicMemoryManager
D3D12DynamicMemoryManager(IMemoryAllocator &Allocator, RenderDeviceD3D12Impl &DeviceD3D12Impl, Uint32 NumPagesToReserve, Uint64 PageSize)
Definition: D3D12DynamicHeap.cpp:78
Diligent::Uint32
uint32_t Uint32
32-bit unsigned integer
Definition: BasicTypes.h:51
Diligent::D3D12DynamicHeap::~D3D12DynamicHeap
~D3D12DynamicHeap()
Definition: D3D12DynamicHeap.cpp:179
Diligent::D3D12DynamicHeap::Allocate
D3D12DynamicAllocation Allocate(Uint64 SizeInBytes, Uint64 Alignment, Uint64 DvpCtxFrameNumber)
Definition: D3D12DynamicHeap.cpp:195
Diligent::D3D12DynamicMemoryManager::ReleasePages
void ReleasePages(std::vector< D3D12DynamicPage > &Pages, Uint64 QueueMask)
Definition: D3D12DynamicHeap.cpp:113
Diligent::IMemoryAllocator
Base interface for a raw memory allocator.
Definition: MemoryAllocator.h:41
Diligent::D3D12DynamicHeap::D3D12DynamicHeap
D3D12DynamicHeap(D3D12DynamicMemoryManager &DynamicMemMgr, std::string HeapName, Uint64 PageSize)
Definition: D3D12DynamicHeap.hpp:167
Diligent::D3D12DynamicPage::D3D12DynamicPage
D3D12DynamicPage(ID3D12Device *pd3d12Device, Uint64 Size)
Definition: D3D12DynamicHeap.cpp:35
Diligent::D3D12DynamicAllocation::CPUAddress
void * CPUAddress
Definition: D3D12DynamicHeap.hpp:68
Diligent::D3D12DynamicAllocation::pBuffer
ID3D12Resource * pBuffer
Definition: D3D12DynamicHeap.hpp:65
Diligent::Uint8
uint8_t Uint8
8-bit unsigned integer
Definition: BasicTypes.h:53
Diligent::D3D12DynamicAllocation::Offset
Uint64 Offset
Definition: D3D12DynamicHeap.hpp:66
VERIFY_EXPR
#define VERIFY_EXPR(...)
Definition: DebugUtilities.hpp:79
VERIFY
#define VERIFY(...)
Definition: DebugUtilities.hpp:76
Diligent::D3D12DynamicPage::GetSize
Uint64 GetSize() const
Definition: D3D12DynamicHeap.hpp:107
Diligent::D3D12DynamicAllocation
Definition: D3D12DynamicHeap.hpp:40
Diligent::D3D12DynamicAllocation::GPUAddress
D3D12_GPU_VIRTUAL_ADDRESS GPUAddress
Definition: D3D12DynamicHeap.hpp:69
Diligent::D3D12DynamicMemoryManager::Destroy
void Destroy()
Definition: D3D12DynamicHeap.cpp:158
Diligent::D3D12DynamicPage::GetCPUAddress
void * GetCPUAddress(Uint64 Offset)
Definition: D3D12DynamicHeap.hpp:88
Diligent::D3D12DynamicAllocation::Size
Uint64 Size
Definition: D3D12DynamicHeap.hpp:67
Diligent::D3D12DynamicHeap::ReleaseAllocatedPages
void ReleaseAllocatedPages(Uint64 QueueMask)
Definition: D3D12DynamicHeap.cpp:252
Diligent
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37
Diligent::D3D12DynamicAllocation::D3D12DynamicAllocation
D3D12DynamicAllocation() noexcept
Definition: D3D12DynamicHeap.hpp:42