Diligent Engine  v.2.4.g
VulkanUploadHeap.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 <unordered_map>
33 
34 namespace Diligent
35 {
36 
37 // Upload heap is used by a device context to update texture and buffer regions through
38 // UpdateBufferRegion() and UpdateTextureRegion().
39 //
40 // The heap allocates pages from the global memory manager.
41 // The pages are released and returned to the manager at the end of every frame.
42 //
43 // _______________________________________________________________________________________________________________________________
44 // | |
45 // | VulkanUploadHeap |
46 // | |
47 // | || - - - - - - - - - - Page[0] - - - - - - - - - - -|| || - - - - - - - - - - Page[1] - - - - - - - - - - -|| |
48 // | || Allocation0 | Allocation1 | ... | AllocationN || || Allocation0 | Allocation1 | ... | AllocationM || ... |
49 // |__________|____________________________________________________________________________________________________________________|
50 // | A |
51 // | | |
52 // |Allocate() CreateNewPage()| |ReleaseAllocatedPages()
53 // | ______|___________________V____
54 // V | |
55 // VulkanUploadAllocation | Global Memory Manager |
56 // | (VulkanMemoryManager) |
57 // | |
58 // |______________________________|
59 //
60 class RenderDeviceVkImpl;
61 
63 {
64  VulkanUploadAllocation() noexcept {}
65  // clang-format off
66  VulkanUploadAllocation(void* _CPUAddress,
67  VkDeviceSize _Size,
68  VkDeviceSize _AlignedOffset,
69  VkBuffer _vkBuffer) noexcept :
70  vkBuffer {_vkBuffer },
71  CPUAddress {_CPUAddress },
72  Size {_Size },
73  AlignedOffset{_AlignedOffset}
74  {}
79  // clang-format on
80 
81  VkBuffer vkBuffer = VK_NULL_HANDLE; // Vulkan buffer associated with this memory.
82  void* CPUAddress = nullptr;
83  VkDeviceSize Size = 0;
84  VkDeviceSize AlignedOffset = 0;
85 };
86 
88 {
89 public:
91  std::string HeapName,
92  VkDeviceSize PageSize);
93 
94  // clang-format off
95  VulkanUploadHeap (const VulkanUploadHeap&) = delete;
96  VulkanUploadHeap ( VulkanUploadHeap&&) = delete;
99  // clang-format on
100 
102 
103  VulkanUploadAllocation Allocate(VkDeviceSize SizeInBytes, VkDeviceSize Alignment);
104 
105  // Releases all allocated pages that are later returned to the global memory manager by the release queues.
106  // As global memory manager is hosted by the render device, the upload heap can be destroyed before the
107  // pages are actually returned to the manager.
108  void ReleaseAllocatedPages(Uint64 CmdQueueMask);
109 
110  size_t GetStalePagesCount() const
111  {
112  return m_Pages.size();
113  }
114 
115 private:
116  RenderDeviceVkImpl& m_RenderDevice;
117  std::string m_HeapName;
118  const VkDeviceSize m_PageSize;
119 
120  struct UploadPageInfo
121  {
122  // clang-format off
123  UploadPageInfo(VulkanUtilities::VulkanMemoryAllocation&& _MemAllocation,
125  Uint8* _CPUAddress) :
126  MemAllocation{std::move(_MemAllocation)},
127  Buffer {std::move(_Buffer) },
128  CPUAddress {_CPUAddress }
129  {
130  }
131  // clang-format on
132 
135  Uint8* const CPUAddress = nullptr;
136  };
137  std::vector<UploadPageInfo> m_Pages;
138 
139  struct CurrPageInfo
140  {
141  VkBuffer vkBuffer = VK_NULL_HANDLE;
142  Uint8* CurrCPUAddress = nullptr;
143  VkDeviceSize CurrOffset = 0;
144  VkDeviceSize AvailableSize = 0;
145 
146  void Reset(UploadPageInfo& NewPage, VkDeviceSize PageSize)
147  {
148  vkBuffer = NewPage.Buffer;
149  CurrCPUAddress = NewPage.CPUAddress;
150  CurrOffset = 0;
151  AvailableSize = PageSize;
152  }
153 
154  void Advance(VkDeviceSize SizeInBytes)
155  {
156  CurrCPUAddress += SizeInBytes;
157  CurrOffset += SizeInBytes;
158  AvailableSize -= SizeInBytes;
159  }
160  } m_CurrPage;
161 
162  VkDeviceSize m_CurrFrameSize = 0;
163  VkDeviceSize m_PeakFrameSize = 0;
164  VkDeviceSize m_CurrAllocatedSize = 0;
165  VkDeviceSize m_PeakAllocatedSize = 0;
166 
167  UploadPageInfo CreateNewPage(VkDeviceSize SizeInBytes) const;
168 };
169 
170 } // namespace Diligent
Diligent::RenderDeviceVkImpl
Render device implementation in Vulkan backend.
Definition: RenderDeviceVkImpl.hpp:58
Diligent::Uint64
uint64_t Uint64
64-bit unsigned integer
Definition: BasicTypes.h:50
Diligent::VulkanUploadHeap::ReleaseAllocatedPages
void ReleaseAllocatedPages(Uint64 CmdQueueMask)
Definition: VulkanUploadHeap.cpp:140
Diligent::VulkanUploadAllocation::operator=
VulkanUploadAllocation & operator=(const VulkanUploadAllocation &)=delete
Diligent::VulkanUploadHeap
Definition: VulkanUploadHeap.hpp:87
Diligent::VulkanUploadHeap::Allocate
VulkanUploadAllocation Allocate(VkDeviceSize SizeInBytes, VkDeviceSize Alignment)
Definition: VulkanUploadHeap.cpp:93
Diligent::VulkanUploadHeap::operator=
VulkanUploadHeap & operator=(const VulkanUploadHeap &)=delete
VulkanUtilities::BufferWrapper
DEFINE_VULKAN_OBJECT_WRAPPER(Buffer) BufferWrapper
Definition: VulkanLogicalDevice.hpp:69
Diligent::VulkanUploadAllocation::CPUAddress
void * CPUAddress
Definition: VulkanUploadHeap.hpp:82
VulkanUtilities::VulkanHandleTypeId::Buffer
@ Buffer
Diligent::VulkanUploadAllocation::VulkanUploadAllocation
VulkanUploadAllocation(void *_CPUAddress, VkDeviceSize _Size, VkDeviceSize _AlignedOffset, VkBuffer _vkBuffer) noexcept
Definition: VulkanUploadHeap.hpp:66
Diligent::VulkanUploadAllocation
Definition: VulkanUploadHeap.hpp:62
Diligent::VulkanUploadAllocation::AlignedOffset
VkDeviceSize AlignedOffset
Definition: VulkanUploadHeap.hpp:84
Diligent::VulkanUploadHeap::VulkanUploadHeap
VulkanUploadHeap(RenderDeviceVkImpl &RenderDevice, std::string HeapName, VkDeviceSize PageSize)
Definition: VulkanUploadHeap.cpp:35
Diligent::VulkanUploadHeap::GetStalePagesCount
size_t GetStalePagesCount() const
Definition: VulkanUploadHeap.hpp:110
Diligent::VulkanUploadAllocation::VulkanUploadAllocation
VulkanUploadAllocation() noexcept
Definition: VulkanUploadHeap.hpp:64
Diligent::VulkanUploadAllocation::vkBuffer
VkBuffer vkBuffer
Definition: VulkanUploadHeap.hpp:81
Diligent::VulkanUploadAllocation::Size
VkDeviceSize Size
Definition: VulkanUploadHeap.hpp:83
Diligent::Uint8
uint8_t Uint8
8-bit unsigned integer
Definition: BasicTypes.h:53
Diligent::VulkanUploadHeap::~VulkanUploadHeap
~VulkanUploadHeap()
Definition: VulkanUploadHeap.cpp:46
VulkanObjectWrappers.hpp
VulkanUtilities::VulkanMemoryAllocation
Definition: VulkanMemoryManager.hpp:48
VulkanMemoryManager.hpp
Diligent
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37