1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // vma_allocator_wrapper.cpp:
7 // Hides VMA functions so we can use separate warning sets.
8 //
9
10 #include "vk_mem_alloc_wrapper.h"
11
12 #include <vk_mem_alloc.h>
13
14 namespace vma
15 {
16 #define VALIDATE_BLOCK_CREATE_FLAG_BITS(x) \
17 static_assert(static_cast<uint32_t>(x) == \
18 static_cast<uint32_t>(VMA_VIRTUAL_BLOCK_CREATE_##x##_ALGORITHM_BIT), \
19 "VMA enum mismatch")
20 VALIDATE_BLOCK_CREATE_FLAG_BITS(LINEAR);
21
InitAllocator(VkPhysicalDevice physicalDevice,VkDevice device,VkInstance instance,uint32_t apiVersion,VkDeviceSize preferredLargeHeapBlockSize,VmaAllocator * pAllocator)22 VkResult InitAllocator(VkPhysicalDevice physicalDevice,
23 VkDevice device,
24 VkInstance instance,
25 uint32_t apiVersion,
26 VkDeviceSize preferredLargeHeapBlockSize,
27 VmaAllocator *pAllocator)
28 {
29 VmaVulkanFunctions funcs = {};
30 funcs.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties;
31 funcs.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
32 funcs.vkAllocateMemory = vkAllocateMemory;
33 funcs.vkFreeMemory = vkFreeMemory;
34 funcs.vkMapMemory = vkMapMemory;
35 funcs.vkUnmapMemory = vkUnmapMemory;
36 funcs.vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges;
37 funcs.vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges;
38 funcs.vkBindBufferMemory = vkBindBufferMemory;
39 funcs.vkBindImageMemory = vkBindImageMemory;
40 funcs.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements;
41 funcs.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements;
42 funcs.vkCreateBuffer = vkCreateBuffer;
43 funcs.vkDestroyBuffer = vkDestroyBuffer;
44 funcs.vkCreateImage = vkCreateImage;
45 funcs.vkDestroyImage = vkDestroyImage;
46 funcs.vkCmdCopyBuffer = vkCmdCopyBuffer;
47 {
48 funcs.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2;
49 funcs.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2;
50 funcs.vkBindBufferMemory2KHR = vkBindBufferMemory2;
51 funcs.vkBindImageMemory2KHR = vkBindImageMemory2;
52 funcs.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2;
53 }
54
55 VmaAllocatorCreateInfo allocatorInfo = {};
56 allocatorInfo.physicalDevice = physicalDevice;
57 allocatorInfo.device = device;
58 allocatorInfo.instance = instance;
59 allocatorInfo.pVulkanFunctions = &funcs;
60 allocatorInfo.vulkanApiVersion = apiVersion;
61 allocatorInfo.preferredLargeHeapBlockSize = preferredLargeHeapBlockSize;
62
63 return vmaCreateAllocator(&allocatorInfo, pAllocator);
64 }
65
DestroyAllocator(VmaAllocator allocator)66 void DestroyAllocator(VmaAllocator allocator)
67 {
68 vmaDestroyAllocator(allocator);
69 }
70
CreatePool(VmaAllocator allocator,uint32_t memoryTypeIndex,VkDeviceSize blockSize,VmaPool * pPool)71 VkResult CreatePool(VmaAllocator allocator,
72 uint32_t memoryTypeIndex,
73 VkDeviceSize blockSize,
74 VmaPool *pPool)
75 {
76 VmaPoolCreateInfo poolCreateInfo = {};
77 poolCreateInfo.memoryTypeIndex = memoryTypeIndex;
78 poolCreateInfo.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT;
79 poolCreateInfo.blockSize = blockSize;
80 poolCreateInfo.maxBlockCount = -1; // unlimited
81 return vmaCreatePool(allocator, &poolCreateInfo, pPool);
82 }
83
DestroyPool(VmaAllocator allocator,VmaPool pool)84 void DestroyPool(VmaAllocator allocator, VmaPool pool)
85 {
86 vmaDestroyPool(allocator, pool);
87 }
88
FreeMemory(VmaAllocator allocator,VmaAllocation allocation)89 void FreeMemory(VmaAllocator allocator, VmaAllocation allocation)
90 {
91 vmaFreeMemory(allocator, allocation);
92 }
93
CreateBuffer(VmaAllocator allocator,const VkBufferCreateInfo * pBufferCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool persistentlyMapped,uint32_t * pMemoryTypeIndexOut,VkBuffer * pBuffer,VmaAllocation * pAllocation)94 VkResult CreateBuffer(VmaAllocator allocator,
95 const VkBufferCreateInfo *pBufferCreateInfo,
96 VkMemoryPropertyFlags requiredFlags,
97 VkMemoryPropertyFlags preferredFlags,
98 bool persistentlyMapped,
99 uint32_t *pMemoryTypeIndexOut,
100 VkBuffer *pBuffer,
101 VmaAllocation *pAllocation)
102 {
103 VkResult result;
104 VmaAllocationCreateInfo allocationCreateInfo = {};
105 allocationCreateInfo.requiredFlags = requiredFlags;
106 allocationCreateInfo.preferredFlags = preferredFlags;
107 allocationCreateInfo.flags = (persistentlyMapped) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
108 VmaAllocationInfo allocationInfo = {};
109
110 result = vmaCreateBuffer(allocator, pBufferCreateInfo, &allocationCreateInfo, pBuffer,
111 pAllocation, &allocationInfo);
112 *pMemoryTypeIndexOut = allocationInfo.memoryType;
113
114 return result;
115 }
116
AllocateAndBindMemoryForImage(VmaAllocator allocator,VkImage * pImage,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,uint32_t memoryTypeBits,bool allocateDedicatedMemory,VmaAllocation * pAllocationOut,uint32_t * pMemoryTypeIndexOut,VkDeviceSize * sizeOut)117 VkResult AllocateAndBindMemoryForImage(VmaAllocator allocator,
118 VkImage *pImage,
119 VkMemoryPropertyFlags requiredFlags,
120 VkMemoryPropertyFlags preferredFlags,
121 uint32_t memoryTypeBits,
122 bool allocateDedicatedMemory,
123 VmaAllocation *pAllocationOut,
124 uint32_t *pMemoryTypeIndexOut,
125 VkDeviceSize *sizeOut)
126 {
127 VkResult result;
128 VmaAllocationCreateInfo allocationCreateInfo = {};
129 allocationCreateInfo.requiredFlags = requiredFlags;
130 allocationCreateInfo.preferredFlags = preferredFlags;
131 allocationCreateInfo.memoryTypeBits = memoryTypeBits;
132 allocationCreateInfo.flags =
133 allocateDedicatedMemory ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0;
134 VmaAllocationInfo allocationInfo = {};
135
136 result = vmaAllocateMemoryForImage(allocator, *pImage, &allocationCreateInfo, pAllocationOut,
137 &allocationInfo);
138 if (result == VK_SUCCESS)
139 {
140 // If binding was unsuccessful, we should free the allocation.
141 result = vmaBindImageMemory(allocator, *pAllocationOut, *pImage);
142 if (result != VK_SUCCESS)
143 {
144 vmaFreeMemory(allocator, *pAllocationOut);
145 *pAllocationOut = VK_NULL_HANDLE;
146 return result;
147 }
148
149 *pMemoryTypeIndexOut = allocationInfo.memoryType;
150 *sizeOut = allocationInfo.size;
151 }
152
153 return result;
154 }
155
FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,const VkBufferCreateInfo * pBufferCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool persistentlyMappedBuffers,uint32_t * pMemoryTypeIndexOut)156 VkResult FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,
157 const VkBufferCreateInfo *pBufferCreateInfo,
158 VkMemoryPropertyFlags requiredFlags,
159 VkMemoryPropertyFlags preferredFlags,
160 bool persistentlyMappedBuffers,
161 uint32_t *pMemoryTypeIndexOut)
162 {
163 VmaAllocationCreateInfo allocationCreateInfo = {};
164 allocationCreateInfo.requiredFlags = requiredFlags;
165 allocationCreateInfo.preferredFlags = preferredFlags;
166 allocationCreateInfo.flags = (persistentlyMappedBuffers) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
167
168 return vmaFindMemoryTypeIndexForBufferInfo(allocator, pBufferCreateInfo, &allocationCreateInfo,
169 pMemoryTypeIndexOut);
170 }
171
FindMemoryTypeIndexForImageInfo(VmaAllocator allocator,const VkImageCreateInfo * pImageCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool allocateDedicatedMemory,uint32_t * pMemoryTypeIndexOut)172 VkResult FindMemoryTypeIndexForImageInfo(VmaAllocator allocator,
173 const VkImageCreateInfo *pImageCreateInfo,
174 VkMemoryPropertyFlags requiredFlags,
175 VkMemoryPropertyFlags preferredFlags,
176 bool allocateDedicatedMemory,
177 uint32_t *pMemoryTypeIndexOut)
178 {
179 VmaAllocationCreateInfo allocationCreateInfo = {};
180 allocationCreateInfo.requiredFlags = requiredFlags;
181 allocationCreateInfo.preferredFlags = preferredFlags;
182 allocationCreateInfo.flags =
183 allocateDedicatedMemory ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0;
184
185 return vmaFindMemoryTypeIndexForImageInfo(allocator, pImageCreateInfo, &allocationCreateInfo,
186 pMemoryTypeIndexOut);
187 }
188
GetMemoryTypeProperties(VmaAllocator allocator,uint32_t memoryTypeIndex,VkMemoryPropertyFlags * pFlags)189 void GetMemoryTypeProperties(VmaAllocator allocator,
190 uint32_t memoryTypeIndex,
191 VkMemoryPropertyFlags *pFlags)
192 {
193 vmaGetMemoryTypeProperties(allocator, memoryTypeIndex, pFlags);
194 }
195
MapMemory(VmaAllocator allocator,VmaAllocation allocation,void ** ppData)196 VkResult MapMemory(VmaAllocator allocator, VmaAllocation allocation, void **ppData)
197 {
198 return vmaMapMemory(allocator, allocation, ppData);
199 }
200
UnmapMemory(VmaAllocator allocator,VmaAllocation allocation)201 void UnmapMemory(VmaAllocator allocator, VmaAllocation allocation)
202 {
203 return vmaUnmapMemory(allocator, allocation);
204 }
205
FlushAllocation(VmaAllocator allocator,VmaAllocation allocation,VkDeviceSize offset,VkDeviceSize size)206 void FlushAllocation(VmaAllocator allocator,
207 VmaAllocation allocation,
208 VkDeviceSize offset,
209 VkDeviceSize size)
210 {
211 vmaFlushAllocation(allocator, allocation, offset, size);
212 }
213
InvalidateAllocation(VmaAllocator allocator,VmaAllocation allocation,VkDeviceSize offset,VkDeviceSize size)214 void InvalidateAllocation(VmaAllocator allocator,
215 VmaAllocation allocation,
216 VkDeviceSize offset,
217 VkDeviceSize size)
218 {
219 vmaInvalidateAllocation(allocator, allocation, offset, size);
220 }
221
BuildStatsString(VmaAllocator allocator,char ** statsString,VkBool32 detailedMap)222 void BuildStatsString(VmaAllocator allocator, char **statsString, VkBool32 detailedMap)
223 {
224 vmaBuildStatsString(allocator, statsString, detailedMap);
225 }
226
FreeStatsString(VmaAllocator allocator,char * statsString)227 void FreeStatsString(VmaAllocator allocator, char *statsString)
228 {
229 vmaFreeStatsString(allocator, statsString);
230 }
231
232 // VmaVirtualBlock implementation
CreateVirtualBlock(VkDeviceSize size,VirtualBlockCreateFlags flags,VmaVirtualBlock * pVirtualBlock)233 VkResult CreateVirtualBlock(VkDeviceSize size,
234 VirtualBlockCreateFlags flags,
235 VmaVirtualBlock *pVirtualBlock)
236 {
237 VmaVirtualBlockCreateInfo virtualBlockCreateInfo = {};
238 virtualBlockCreateInfo.size = size;
239 virtualBlockCreateInfo.flags = (VmaVirtualBlockCreateFlagBits)flags;
240 return vmaCreateVirtualBlock(&virtualBlockCreateInfo, pVirtualBlock);
241 }
242
DestroyVirtualBlock(VmaVirtualBlock virtualBlock)243 void DestroyVirtualBlock(VmaVirtualBlock virtualBlock)
244 {
245 vmaDestroyVirtualBlock(virtualBlock);
246 }
247
VirtualAllocate(VmaVirtualBlock virtualBlock,VkDeviceSize size,VkDeviceSize alignment,VmaVirtualAllocation * pAllocation,VkDeviceSize * pOffset)248 VkResult VirtualAllocate(VmaVirtualBlock virtualBlock,
249 VkDeviceSize size,
250 VkDeviceSize alignment,
251 VmaVirtualAllocation *pAllocation,
252 VkDeviceSize *pOffset)
253 {
254 VmaVirtualAllocationCreateInfo createInfo = {};
255 createInfo.size = size;
256 createInfo.alignment = alignment;
257 createInfo.flags = 0;
258 return vmaVirtualAllocate(virtualBlock, &createInfo, pAllocation, pOffset);
259 }
260
VirtualFree(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset)261 void VirtualFree(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, VkDeviceSize offset)
262 {
263 vmaVirtualFree(virtualBlock, allocation);
264 }
265
IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)266 VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)
267 {
268 return vmaIsVirtualBlockEmpty(virtualBlock);
269 }
270
GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset,VkDeviceSize * sizeOut,void ** pUserDataOut)271 void GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,
272 VmaVirtualAllocation allocation,
273 VkDeviceSize offset,
274 VkDeviceSize *sizeOut,
275 void **pUserDataOut)
276 {
277 VmaVirtualAllocationInfo virtualAllocInfo = {};
278 vmaGetVirtualAllocationInfo(virtualBlock, allocation, &virtualAllocInfo);
279 *sizeOut = virtualAllocInfo.size;
280 *pUserDataOut = virtualAllocInfo.pUserData;
281 }
282
ClearVirtualBlock(VmaVirtualBlock virtualBlock)283 void ClearVirtualBlock(VmaVirtualBlock virtualBlock)
284 {
285 vmaClearVirtualBlock(virtualBlock);
286 }
287
SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset,void * pUserData)288 void SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,
289 VmaVirtualAllocation allocation,
290 VkDeviceSize offset,
291 void *pUserData)
292 {
293 vmaSetVirtualAllocationUserData(virtualBlock, allocation, pUserData);
294 }
295
CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock,StatInfo * pStatInfo)296 void CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, StatInfo *pStatInfo)
297 {
298 vmaCalculateVirtualBlockStatistics(virtualBlock,
299 reinterpret_cast<VmaDetailedStatistics *>(pStatInfo));
300 }
301
BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,char ** ppStatsString,VkBool32 detailedMap)302 void BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,
303 char **ppStatsString,
304 VkBool32 detailedMap)
305 {
306 vmaBuildVirtualBlockStatsString(virtualBlock, ppStatsString, detailedMap);
307 }
308
FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock,char * pStatsString)309 void FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock, char *pStatsString)
310 {
311 vmaFreeVirtualBlockStatsString(virtualBlock, pStatsString);
312 }
313 } // namespace vma
314