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
FreeMemory(VmaAllocator allocator,VmaAllocation allocation)71 void FreeMemory(VmaAllocator allocator, VmaAllocation allocation)
72 {
73 vmaFreeMemory(allocator, allocation);
74 }
75
CreateBuffer(VmaAllocator allocator,const VkBufferCreateInfo * pBufferCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool persistentlyMapped,uint32_t * pMemoryTypeIndexOut,VkBuffer * pBuffer,VmaAllocation * pAllocation)76 VkResult CreateBuffer(VmaAllocator allocator,
77 const VkBufferCreateInfo *pBufferCreateInfo,
78 VkMemoryPropertyFlags requiredFlags,
79 VkMemoryPropertyFlags preferredFlags,
80 bool persistentlyMapped,
81 uint32_t *pMemoryTypeIndexOut,
82 VkBuffer *pBuffer,
83 VmaAllocation *pAllocation)
84 {
85 VkResult result;
86 VmaAllocationCreateInfo allocationCreateInfo = {};
87 allocationCreateInfo.requiredFlags = requiredFlags;
88 allocationCreateInfo.preferredFlags = preferredFlags;
89 allocationCreateInfo.flags = (persistentlyMapped) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
90 VmaAllocationInfo allocationInfo = {};
91
92 result = vmaCreateBuffer(allocator, pBufferCreateInfo, &allocationCreateInfo, pBuffer,
93 pAllocation, &allocationInfo);
94 *pMemoryTypeIndexOut = allocationInfo.memoryType;
95
96 return result;
97 }
98
AllocateAndBindMemoryForImage(VmaAllocator allocator,VkImage * pImage,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,uint32_t memoryTypeBits,bool allocateDedicatedMemory,VmaAllocation * pAllocationOut,uint32_t * pMemoryTypeIndexOut,VkDeviceSize * sizeOut)99 VkResult AllocateAndBindMemoryForImage(VmaAllocator allocator,
100 VkImage *pImage,
101 VkMemoryPropertyFlags requiredFlags,
102 VkMemoryPropertyFlags preferredFlags,
103 uint32_t memoryTypeBits,
104 bool allocateDedicatedMemory,
105 VmaAllocation *pAllocationOut,
106 uint32_t *pMemoryTypeIndexOut,
107 VkDeviceSize *sizeOut)
108 {
109 VkResult result;
110 VmaAllocationCreateInfo allocationCreateInfo = {};
111 allocationCreateInfo.requiredFlags = requiredFlags;
112 allocationCreateInfo.preferredFlags = preferredFlags;
113 allocationCreateInfo.memoryTypeBits = memoryTypeBits;
114 allocationCreateInfo.flags =
115 allocateDedicatedMemory ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0;
116 VmaAllocationInfo allocationInfo = {};
117
118 result = vmaAllocateMemoryForImage(allocator, *pImage, &allocationCreateInfo, pAllocationOut,
119 &allocationInfo);
120 if (result == VK_SUCCESS)
121 {
122 // If binding was unsuccessful, we should free the allocation.
123 result = vmaBindImageMemory(allocator, *pAllocationOut, *pImage);
124 if (result != VK_SUCCESS)
125 {
126 vmaFreeMemory(allocator, *pAllocationOut);
127 *pAllocationOut = VK_NULL_HANDLE;
128 return result;
129 }
130
131 *pMemoryTypeIndexOut = allocationInfo.memoryType;
132 *sizeOut = allocationInfo.size;
133 }
134
135 return result;
136 }
137
FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,const VkBufferCreateInfo * pBufferCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool persistentlyMappedBuffers,uint32_t * pMemoryTypeIndexOut)138 VkResult FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,
139 const VkBufferCreateInfo *pBufferCreateInfo,
140 VkMemoryPropertyFlags requiredFlags,
141 VkMemoryPropertyFlags preferredFlags,
142 bool persistentlyMappedBuffers,
143 uint32_t *pMemoryTypeIndexOut)
144 {
145 VmaAllocationCreateInfo allocationCreateInfo = {};
146 allocationCreateInfo.requiredFlags = requiredFlags;
147 allocationCreateInfo.preferredFlags = preferredFlags;
148 allocationCreateInfo.flags = (persistentlyMappedBuffers) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
149
150 return vmaFindMemoryTypeIndexForBufferInfo(allocator, pBufferCreateInfo, &allocationCreateInfo,
151 pMemoryTypeIndexOut);
152 }
153
FindMemoryTypeIndexForImageInfo(VmaAllocator allocator,const VkImageCreateInfo * pImageCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool allocateDedicatedMemory,uint32_t * pMemoryTypeIndexOut)154 VkResult FindMemoryTypeIndexForImageInfo(VmaAllocator allocator,
155 const VkImageCreateInfo *pImageCreateInfo,
156 VkMemoryPropertyFlags requiredFlags,
157 VkMemoryPropertyFlags preferredFlags,
158 bool allocateDedicatedMemory,
159 uint32_t *pMemoryTypeIndexOut)
160 {
161 VmaAllocationCreateInfo allocationCreateInfo = {};
162 allocationCreateInfo.requiredFlags = requiredFlags;
163 allocationCreateInfo.preferredFlags = preferredFlags;
164 allocationCreateInfo.flags =
165 allocateDedicatedMemory ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0;
166
167 return vmaFindMemoryTypeIndexForImageInfo(allocator, pImageCreateInfo, &allocationCreateInfo,
168 pMemoryTypeIndexOut);
169 }
170
GetMemoryTypeProperties(VmaAllocator allocator,uint32_t memoryTypeIndex,VkMemoryPropertyFlags * pFlags)171 void GetMemoryTypeProperties(VmaAllocator allocator,
172 uint32_t memoryTypeIndex,
173 VkMemoryPropertyFlags *pFlags)
174 {
175 vmaGetMemoryTypeProperties(allocator, memoryTypeIndex, pFlags);
176 }
177
MapMemory(VmaAllocator allocator,VmaAllocation allocation,void ** ppData)178 VkResult MapMemory(VmaAllocator allocator, VmaAllocation allocation, void **ppData)
179 {
180 return vmaMapMemory(allocator, allocation, ppData);
181 }
182
UnmapMemory(VmaAllocator allocator,VmaAllocation allocation)183 void UnmapMemory(VmaAllocator allocator, VmaAllocation allocation)
184 {
185 return vmaUnmapMemory(allocator, allocation);
186 }
187
FlushAllocation(VmaAllocator allocator,VmaAllocation allocation,VkDeviceSize offset,VkDeviceSize size)188 void FlushAllocation(VmaAllocator allocator,
189 VmaAllocation allocation,
190 VkDeviceSize offset,
191 VkDeviceSize size)
192 {
193 vmaFlushAllocation(allocator, allocation, offset, size);
194 }
195
InvalidateAllocation(VmaAllocator allocator,VmaAllocation allocation,VkDeviceSize offset,VkDeviceSize size)196 void InvalidateAllocation(VmaAllocator allocator,
197 VmaAllocation allocation,
198 VkDeviceSize offset,
199 VkDeviceSize size)
200 {
201 vmaInvalidateAllocation(allocator, allocation, offset, size);
202 }
203
BuildStatsString(VmaAllocator allocator,char ** statsString,VkBool32 detailedMap)204 void BuildStatsString(VmaAllocator allocator, char **statsString, VkBool32 detailedMap)
205 {
206 vmaBuildStatsString(allocator, statsString, detailedMap);
207 }
208
FreeStatsString(VmaAllocator allocator,char * statsString)209 void FreeStatsString(VmaAllocator allocator, char *statsString)
210 {
211 vmaFreeStatsString(allocator, statsString);
212 }
213
214 // VmaVirtualBlock implementation
CreateVirtualBlock(VkDeviceSize size,VirtualBlockCreateFlags flags,VmaVirtualBlock * pVirtualBlock)215 VkResult CreateVirtualBlock(VkDeviceSize size,
216 VirtualBlockCreateFlags flags,
217 VmaVirtualBlock *pVirtualBlock)
218 {
219 VmaVirtualBlockCreateInfo virtualBlockCreateInfo = {};
220 virtualBlockCreateInfo.size = size;
221 virtualBlockCreateInfo.flags = (VmaVirtualBlockCreateFlagBits)flags;
222 return vmaCreateVirtualBlock(&virtualBlockCreateInfo, pVirtualBlock);
223 }
224
DestroyVirtualBlock(VmaVirtualBlock virtualBlock)225 void DestroyVirtualBlock(VmaVirtualBlock virtualBlock)
226 {
227 vmaDestroyVirtualBlock(virtualBlock);
228 }
229
VirtualAllocate(VmaVirtualBlock virtualBlock,VkDeviceSize size,VkDeviceSize alignment,VmaVirtualAllocation * pAllocation,VkDeviceSize * pOffset)230 VkResult VirtualAllocate(VmaVirtualBlock virtualBlock,
231 VkDeviceSize size,
232 VkDeviceSize alignment,
233 VmaVirtualAllocation *pAllocation,
234 VkDeviceSize *pOffset)
235 {
236 VmaVirtualAllocationCreateInfo createInfo = {};
237 createInfo.size = size;
238 createInfo.alignment = alignment;
239 createInfo.flags = 0;
240 return vmaVirtualAllocate(virtualBlock, &createInfo, pAllocation, pOffset);
241 }
242
VirtualFree(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset)243 void VirtualFree(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, VkDeviceSize offset)
244 {
245 vmaVirtualFree(virtualBlock, allocation);
246 }
247
IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)248 VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)
249 {
250 return vmaIsVirtualBlockEmpty(virtualBlock);
251 }
252
GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset,VkDeviceSize * sizeOut,void ** pUserDataOut)253 void GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,
254 VmaVirtualAllocation allocation,
255 VkDeviceSize offset,
256 VkDeviceSize *sizeOut,
257 void **pUserDataOut)
258 {
259 VmaVirtualAllocationInfo virtualAllocInfo = {};
260 vmaGetVirtualAllocationInfo(virtualBlock, allocation, &virtualAllocInfo);
261 *sizeOut = virtualAllocInfo.size;
262 *pUserDataOut = virtualAllocInfo.pUserData;
263 }
264
ClearVirtualBlock(VmaVirtualBlock virtualBlock)265 void ClearVirtualBlock(VmaVirtualBlock virtualBlock)
266 {
267 vmaClearVirtualBlock(virtualBlock);
268 }
269
SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset,void * pUserData)270 void SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,
271 VmaVirtualAllocation allocation,
272 VkDeviceSize offset,
273 void *pUserData)
274 {
275 vmaSetVirtualAllocationUserData(virtualBlock, allocation, pUserData);
276 }
277
CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock,StatInfo * pStatInfo)278 void CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, StatInfo *pStatInfo)
279 {
280 vmaCalculateVirtualBlockStatistics(virtualBlock,
281 reinterpret_cast<VmaDetailedStatistics *>(pStatInfo));
282 }
283
BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,char ** ppStatsString,VkBool32 detailedMap)284 void BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,
285 char **ppStatsString,
286 VkBool32 detailedMap)
287 {
288 vmaBuildVirtualBlockStatsString(virtualBlock, ppStatsString, detailedMap);
289 }
290
FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock,char * pStatsString)291 void FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock, char *pStatsString)
292 {
293 vmaFreeVirtualBlockStatsString(virtualBlock, pStatsString);
294 }
295 } // namespace vma
296