• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if ANGLE_VMA_VERSION < 3000000
22 VALIDATE_BLOCK_CREATE_FLAG_BITS(BUDDY);
23 #endif  // ANGLE_VMA_VERSION < 3000000
24 
InitAllocator(VkPhysicalDevice physicalDevice,VkDevice device,VkInstance instance,uint32_t apiVersion,VkDeviceSize preferredLargeHeapBlockSize,VmaAllocator * pAllocator)25 VkResult InitAllocator(VkPhysicalDevice physicalDevice,
26                        VkDevice device,
27                        VkInstance instance,
28                        uint32_t apiVersion,
29                        VkDeviceSize preferredLargeHeapBlockSize,
30                        VmaAllocator *pAllocator)
31 {
32     VmaVulkanFunctions funcs                  = {};
33     funcs.vkGetPhysicalDeviceProperties       = vkGetPhysicalDeviceProperties;
34     funcs.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
35     funcs.vkAllocateMemory                    = vkAllocateMemory;
36     funcs.vkFreeMemory                        = vkFreeMemory;
37     funcs.vkMapMemory                         = vkMapMemory;
38     funcs.vkUnmapMemory                       = vkUnmapMemory;
39     funcs.vkFlushMappedMemoryRanges           = vkFlushMappedMemoryRanges;
40     funcs.vkInvalidateMappedMemoryRanges      = vkInvalidateMappedMemoryRanges;
41     funcs.vkBindBufferMemory                  = vkBindBufferMemory;
42     funcs.vkBindImageMemory                   = vkBindImageMemory;
43     funcs.vkGetBufferMemoryRequirements       = vkGetBufferMemoryRequirements;
44     funcs.vkGetImageMemoryRequirements        = vkGetImageMemoryRequirements;
45     funcs.vkCreateBuffer                      = vkCreateBuffer;
46     funcs.vkDestroyBuffer                     = vkDestroyBuffer;
47     funcs.vkCreateImage                       = vkCreateImage;
48     funcs.vkDestroyImage                      = vkDestroyImage;
49     funcs.vkCmdCopyBuffer                     = vkCmdCopyBuffer;
50     {
51 #if !defined(ANGLE_SHARED_LIBVULKAN)
52         // When the vulkan-loader is statically linked, we need to use the extension
53         // functions defined in ANGLE's rx namespace. When it's dynamically linked
54         // with volk, this will default to the function definitions with no namespace
55         using rx::vkBindBufferMemory2KHR;
56         using rx::vkBindImageMemory2KHR;
57         using rx::vkGetBufferMemoryRequirements2KHR;
58         using rx::vkGetImageMemoryRequirements2KHR;
59         using rx::vkGetPhysicalDeviceMemoryProperties2KHR;
60 #endif  // !defined(ANGLE_SHARED_LIBVULKAN)
61         funcs.vkGetBufferMemoryRequirements2KHR       = vkGetBufferMemoryRequirements2KHR;
62         funcs.vkGetImageMemoryRequirements2KHR        = vkGetImageMemoryRequirements2KHR;
63         funcs.vkBindBufferMemory2KHR                  = vkBindBufferMemory2KHR;
64         funcs.vkBindImageMemory2KHR                   = vkBindImageMemory2KHR;
65         funcs.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2KHR;
66     }
67 
68     VmaAllocatorCreateInfo allocatorInfo      = {};
69     allocatorInfo.physicalDevice              = physicalDevice;
70     allocatorInfo.device                      = device;
71     allocatorInfo.instance                    = instance;
72     allocatorInfo.pVulkanFunctions            = &funcs;
73     allocatorInfo.vulkanApiVersion            = apiVersion;
74     allocatorInfo.preferredLargeHeapBlockSize = preferredLargeHeapBlockSize;
75 
76     return vmaCreateAllocator(&allocatorInfo, pAllocator);
77 }
78 
DestroyAllocator(VmaAllocator allocator)79 void DestroyAllocator(VmaAllocator allocator)
80 {
81     vmaDestroyAllocator(allocator);
82 }
83 
CreatePool(VmaAllocator allocator,uint32_t memoryTypeIndex,bool buddyAlgorithm,VkDeviceSize blockSize,VmaPool * pPool)84 VkResult CreatePool(VmaAllocator allocator,
85                     uint32_t memoryTypeIndex,
86 #if ANGLE_VMA_VERSION < 3000000
87                     bool buddyAlgorithm,
88 #endif  // ANGLE_VMA_VERSION < 3000000
89                     VkDeviceSize blockSize,
90                     VmaPool *pPool)
91 {
92     VmaPoolCreateInfo poolCreateInfo = {};
93     poolCreateInfo.memoryTypeIndex   = memoryTypeIndex;
94     poolCreateInfo.flags             = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT;
95 #if ANGLE_VMA_VERSION < 3000000
96     if (buddyAlgorithm)
97     {
98         poolCreateInfo.flags |= VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT;
99     }
100 #endif
101     poolCreateInfo.blockSize     = blockSize;
102     poolCreateInfo.maxBlockCount = -1;  // unlimited
103     return vmaCreatePool(allocator, &poolCreateInfo, pPool);
104 }
105 
DestroyPool(VmaAllocator allocator,VmaPool pool)106 void DestroyPool(VmaAllocator allocator, VmaPool pool)
107 {
108     vmaDestroyPool(allocator, pool);
109 }
110 
FreeMemory(VmaAllocator allocator,VmaAllocation allocation)111 void FreeMemory(VmaAllocator allocator, VmaAllocation allocation)
112 {
113     vmaFreeMemory(allocator, allocation);
114 }
115 
CreateBuffer(VmaAllocator allocator,const VkBufferCreateInfo * pBufferCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool persistentlyMapped,uint32_t * pMemoryTypeIndexOut,VkBuffer * pBuffer,VmaAllocation * pAllocation)116 VkResult CreateBuffer(VmaAllocator allocator,
117                       const VkBufferCreateInfo *pBufferCreateInfo,
118                       VkMemoryPropertyFlags requiredFlags,
119                       VkMemoryPropertyFlags preferredFlags,
120                       bool persistentlyMapped,
121                       uint32_t *pMemoryTypeIndexOut,
122                       VkBuffer *pBuffer,
123                       VmaAllocation *pAllocation)
124 {
125     VkResult result;
126     VmaAllocationCreateInfo allocationCreateInfo = {};
127     allocationCreateInfo.requiredFlags           = requiredFlags;
128     allocationCreateInfo.preferredFlags          = preferredFlags;
129     allocationCreateInfo.flags       = (persistentlyMapped) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
130     VmaAllocationInfo allocationInfo = {};
131 
132     result = vmaCreateBuffer(allocator, pBufferCreateInfo, &allocationCreateInfo, pBuffer,
133                              pAllocation, &allocationInfo);
134     *pMemoryTypeIndexOut = allocationInfo.memoryType;
135 
136     return result;
137 }
138 
AllocateAndBindMemoryForImage(VmaAllocator allocator,VkImage * pImage,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool allocateDedicatedMemory,VmaAllocation * pAllocationOut,uint32_t * pMemoryTypeIndexOut,VkDeviceSize * sizeOut)139 VkResult AllocateAndBindMemoryForImage(VmaAllocator allocator,
140                                        VkImage *pImage,
141                                        VkMemoryPropertyFlags requiredFlags,
142                                        VkMemoryPropertyFlags preferredFlags,
143                                        bool allocateDedicatedMemory,
144                                        VmaAllocation *pAllocationOut,
145                                        uint32_t *pMemoryTypeIndexOut,
146                                        VkDeviceSize *sizeOut)
147 {
148     VkResult result;
149     VmaAllocationCreateInfo allocationCreateInfo = {};
150     allocationCreateInfo.requiredFlags           = requiredFlags;
151     allocationCreateInfo.preferredFlags          = preferredFlags;
152     allocationCreateInfo.flags =
153         allocateDedicatedMemory ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0;
154     VmaAllocationInfo allocationInfo = {};
155 
156     result = vmaAllocateMemoryForImage(allocator, *pImage, &allocationCreateInfo, pAllocationOut,
157                                        &allocationInfo);
158     if (result == VK_SUCCESS)
159     {
160         // If binding was unsuccessful, we should free the allocation.
161         result = vmaBindImageMemory(allocator, *pAllocationOut, *pImage);
162         if (result != VK_SUCCESS)
163         {
164             vmaFreeMemory(allocator, *pAllocationOut);
165             *pAllocationOut = VK_NULL_HANDLE;
166             return result;
167         }
168 
169         *pMemoryTypeIndexOut = allocationInfo.memoryType;
170         *sizeOut             = allocationInfo.size;
171     }
172 
173     return result;
174 }
175 
FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,const VkBufferCreateInfo * pBufferCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool persistentlyMappedBuffers,uint32_t * pMemoryTypeIndexOut)176 VkResult FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,
177                                           const VkBufferCreateInfo *pBufferCreateInfo,
178                                           VkMemoryPropertyFlags requiredFlags,
179                                           VkMemoryPropertyFlags preferredFlags,
180                                           bool persistentlyMappedBuffers,
181                                           uint32_t *pMemoryTypeIndexOut)
182 {
183     VmaAllocationCreateInfo allocationCreateInfo = {};
184     allocationCreateInfo.requiredFlags           = requiredFlags;
185     allocationCreateInfo.preferredFlags          = preferredFlags;
186     allocationCreateInfo.flags = (persistentlyMappedBuffers) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
187 
188     return vmaFindMemoryTypeIndexForBufferInfo(allocator, pBufferCreateInfo, &allocationCreateInfo,
189                                                pMemoryTypeIndexOut);
190 }
191 
FindMemoryTypeIndexForImageInfo(VmaAllocator allocator,const VkImageCreateInfo * pImageCreateInfo,VkMemoryPropertyFlags requiredFlags,VkMemoryPropertyFlags preferredFlags,bool allocateDedicatedMemory,uint32_t * pMemoryTypeIndexOut)192 VkResult FindMemoryTypeIndexForImageInfo(VmaAllocator allocator,
193                                          const VkImageCreateInfo *pImageCreateInfo,
194                                          VkMemoryPropertyFlags requiredFlags,
195                                          VkMemoryPropertyFlags preferredFlags,
196                                          bool allocateDedicatedMemory,
197                                          uint32_t *pMemoryTypeIndexOut)
198 {
199     VmaAllocationCreateInfo allocationCreateInfo = {};
200     allocationCreateInfo.requiredFlags           = requiredFlags;
201     allocationCreateInfo.preferredFlags          = preferredFlags;
202     allocationCreateInfo.flags =
203         allocateDedicatedMemory ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0;
204 
205     return vmaFindMemoryTypeIndexForImageInfo(allocator, pImageCreateInfo, &allocationCreateInfo,
206                                               pMemoryTypeIndexOut);
207 }
208 
GetMemoryTypeProperties(VmaAllocator allocator,uint32_t memoryTypeIndex,VkMemoryPropertyFlags * pFlags)209 void GetMemoryTypeProperties(VmaAllocator allocator,
210                              uint32_t memoryTypeIndex,
211                              VkMemoryPropertyFlags *pFlags)
212 {
213     vmaGetMemoryTypeProperties(allocator, memoryTypeIndex, pFlags);
214 }
215 
MapMemory(VmaAllocator allocator,VmaAllocation allocation,void ** ppData)216 VkResult MapMemory(VmaAllocator allocator, VmaAllocation allocation, void **ppData)
217 {
218     return vmaMapMemory(allocator, allocation, ppData);
219 }
220 
UnmapMemory(VmaAllocator allocator,VmaAllocation allocation)221 void UnmapMemory(VmaAllocator allocator, VmaAllocation allocation)
222 {
223     return vmaUnmapMemory(allocator, allocation);
224 }
225 
FlushAllocation(VmaAllocator allocator,VmaAllocation allocation,VkDeviceSize offset,VkDeviceSize size)226 void FlushAllocation(VmaAllocator allocator,
227                      VmaAllocation allocation,
228                      VkDeviceSize offset,
229                      VkDeviceSize size)
230 {
231     vmaFlushAllocation(allocator, allocation, offset, size);
232 }
233 
InvalidateAllocation(VmaAllocator allocator,VmaAllocation allocation,VkDeviceSize offset,VkDeviceSize size)234 void InvalidateAllocation(VmaAllocator allocator,
235                           VmaAllocation allocation,
236                           VkDeviceSize offset,
237                           VkDeviceSize size)
238 {
239     vmaInvalidateAllocation(allocator, allocation, offset, size);
240 }
241 
BuildStatsString(VmaAllocator allocator,char ** statsString,VkBool32 detailedMap)242 void BuildStatsString(VmaAllocator allocator, char **statsString, VkBool32 detailedMap)
243 {
244     vmaBuildStatsString(allocator, statsString, detailedMap);
245 }
246 
FreeStatsString(VmaAllocator allocator,char * statsString)247 void FreeStatsString(VmaAllocator allocator, char *statsString)
248 {
249     vmaFreeStatsString(allocator, statsString);
250 }
251 
252 // VmaVirtualBlock implementation
CreateVirtualBlock(VkDeviceSize size,VirtualBlockCreateFlags flags,VmaVirtualBlock * pVirtualBlock)253 VkResult CreateVirtualBlock(VkDeviceSize size,
254                             VirtualBlockCreateFlags flags,
255                             VmaVirtualBlock *pVirtualBlock)
256 {
257     VmaVirtualBlockCreateInfo virtualBlockCreateInfo = {};
258     virtualBlockCreateInfo.size                      = size;
259     virtualBlockCreateInfo.flags                     = (VmaVirtualBlockCreateFlagBits)flags;
260     return vmaCreateVirtualBlock(&virtualBlockCreateInfo, pVirtualBlock);
261 }
262 
DestroyVirtualBlock(VmaVirtualBlock virtualBlock)263 void DestroyVirtualBlock(VmaVirtualBlock virtualBlock)
264 {
265     vmaDestroyVirtualBlock(virtualBlock);
266 }
267 
VirtualAllocate(VmaVirtualBlock virtualBlock,VkDeviceSize size,VkDeviceSize alignment,VmaVirtualAllocation * pAllocation,VkDeviceSize * pOffset)268 VkResult VirtualAllocate(VmaVirtualBlock virtualBlock,
269                          VkDeviceSize size,
270                          VkDeviceSize alignment,
271                          VmaVirtualAllocation *pAllocation,
272                          VkDeviceSize *pOffset)
273 {
274     VmaVirtualAllocationCreateInfo createInfo = {};
275     createInfo.size                           = size;
276     createInfo.alignment                      = alignment;
277     createInfo.flags                          = 0;
278 #if ANGLE_VMA_VERSION < 3000000
279     return vmaVirtualAllocate(virtualBlock, &createInfo, pOffset);
280 #else
281     return vmaVirtualAllocate(virtualBlock, &createInfo, pAllocation, pOffset);
282 #endif  // ANGLE_VMA_VERSION < 3000000
283 }
284 
VirtualFree(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset)285 void VirtualFree(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, VkDeviceSize offset)
286 {
287 #if ANGLE_VMA_VERSION < 3000000
288     vmaVirtualFree(virtualBlock, offset);
289 #else
290     vmaVirtualFree(virtualBlock, allocation);
291 #endif  // ANGLE_VMA_VERSION < 3000000
292 }
293 
IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)294 VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)
295 {
296     return vmaIsVirtualBlockEmpty(virtualBlock);
297 }
298 
GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset,VkDeviceSize * sizeOut,void ** pUserDataOut)299 void GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,
300                               VmaVirtualAllocation allocation,
301                               VkDeviceSize offset,
302                               VkDeviceSize *sizeOut,
303                               void **pUserDataOut)
304 {
305     VmaVirtualAllocationInfo virtualAllocInfo = {};
306 #if ANGLE_VMA_VERSION < 3000000
307     vmaGetVirtualAllocationInfo(virtualBlock, offset, &virtualAllocInfo);
308 #else
309     vmaGetVirtualAllocationInfo(virtualBlock, allocation, &virtualAllocInfo);
310 #endif  // ANGLE_VMA_VERSION < 3000000
311     *sizeOut      = virtualAllocInfo.size;
312     *pUserDataOut = virtualAllocInfo.pUserData;
313 }
314 
ClearVirtualBlock(VmaVirtualBlock virtualBlock)315 void ClearVirtualBlock(VmaVirtualBlock virtualBlock)
316 {
317     vmaClearVirtualBlock(virtualBlock);
318 }
319 
SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,VmaVirtualAllocation allocation,VkDeviceSize offset,void * pUserData)320 void SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,
321                                   VmaVirtualAllocation allocation,
322                                   VkDeviceSize offset,
323                                   void *pUserData)
324 {
325 #if ANGLE_VMA_VERSION < 3000000
326     vmaSetVirtualAllocationUserData(virtualBlock, offset, pUserData);
327 #else
328     vmaSetVirtualAllocationUserData(virtualBlock, allocation, pUserData);
329 #endif  // ANGLE_VMA_VERSION < 3000000
330 }
331 
CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock,StatInfo * pStatInfo)332 void CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, StatInfo *pStatInfo)
333 {
334 #if ANGLE_VMA_VERSION < 3000000
335     vmaCalculateVirtualBlockStats(virtualBlock, reinterpret_cast<VmaStatInfo *>(pStatInfo));
336 #else
337     vmaCalculateVirtualBlockStatistics(virtualBlock,
338                                        reinterpret_cast<VmaDetailedStatistics *>(pStatInfo));
339 #endif  // ANGLE_VMA_VERSION < 3000000
340 }
341 
BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,char ** ppStatsString,VkBool32 detailedMap)342 void BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,
343                                   char **ppStatsString,
344                                   VkBool32 detailedMap)
345 {
346     vmaBuildVirtualBlockStatsString(virtualBlock, ppStatsString, detailedMap);
347 }
348 
FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock,char * pStatsString)349 void FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock, char *pStatsString)
350 {
351     vmaFreeVirtualBlockStatsString(virtualBlock, pStatsString);
352 }
353 }  // namespace vma
354