xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/vk_mem_alloc_wrapper.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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