Hash :
83a670ab
Author :
Date :
2021-10-29T09:12:26
Vulkan: Implement BufferPool using VMA's virtual allocator VMA's allocation calls used to be sub-allocating a pool of memory. What we really want is sub-allocate a VkBuffer object. VMA recently added support to expose the underlying range allocation algorithm via APIs, which user can use it to sub-allocate any object. This CL uses that new virtual allocation API to sub-allocate from a pool of VkBuffers. In this CL we only switched BufferVk::mBuffer to sub-allocate from the BufferPool object. Bug: b/205337962 Change-Id: Ia6ef00c22e58687e375b31bc12ac515fd89f3488 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3266146 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// vma_allocator_wrapper.h:
// Hides VMA functions so we can use separate warning sets.
//
#ifndef LIBANGLE_RENDERER_VULKAN_VK_MEM_ALLOC_WRAPPER_H_
#define LIBANGLE_RENDERER_VULKAN_VK_MEM_ALLOC_WRAPPER_H_
#include "common/vulkan/vk_headers.h"
VK_DEFINE_HANDLE(VmaAllocator)
VK_DEFINE_HANDLE(VmaAllocation)
VK_DEFINE_HANDLE(VmaPool)
VK_DEFINE_HANDLE(VmaVirtualBlock)
namespace vma
{
typedef VkFlags VirtualBlockCreateFlags;
typedef enum VirtualBlockCreateFlagBits
{
GENERAL = 0x0000000,
LINEAR = 0x00000001,
BUDDY = 0x00000002
} VirtualBlockCreateFlagBits;
typedef struct StatInfo
{
// Number of VkDeviceMemory Vulkan memory blocks allocated.
uint32_t blockCount;
// Number of VmaAllocation allocation objects allocated.
uint32_t allocationCount;
// Number of free ranges of memory between allocations.
uint32_t unusedRangeCount;
// Total number of bytes occupied by all allocations.
VkDeviceSize usedBytes;
// Total number of bytes occupied by unused ranges.
VkDeviceSize unusedBytes;
VkDeviceSize allocationSizeMin, allocationSizeAvg, allocationSizeMax;
VkDeviceSize unusedRangeSizeMin, unusedRangeSizeAvg, unusedRangeSizeMax;
} StatInfo;
VkResult InitAllocator(VkPhysicalDevice physicalDevice,
VkDevice device,
VkInstance instance,
uint32_t apiVersion,
VkDeviceSize preferredLargeHeapBlockSize,
VmaAllocator *pAllocator);
void DestroyAllocator(VmaAllocator allocator);
VkResult CreatePool(VmaAllocator allocator,
uint32_t memoryTypeIndex,
bool buddyAlgorithm,
VkDeviceSize blockSize,
VmaPool *pPool);
void DestroyPool(VmaAllocator allocator, VmaPool pool);
void FreeMemory(VmaAllocator allocator, VmaAllocation allocation);
VkResult CreateBuffer(VmaAllocator allocator,
const VkBufferCreateInfo *pBufferCreateInfo,
VkMemoryPropertyFlags requiredFlags,
VkMemoryPropertyFlags preferredFlags,
bool persistentlyMappedBuffers,
uint32_t *pMemoryTypeIndexOut,
VkBuffer *pBuffer,
VmaAllocation *pAllocation);
VkResult FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,
const VkBufferCreateInfo *pBufferCreateInfo,
VkMemoryPropertyFlags requiredFlags,
VkMemoryPropertyFlags preferredFlags,
bool persistentlyMappedBuffers,
uint32_t *pMemoryTypeIndexOut);
void GetMemoryTypeProperties(VmaAllocator allocator,
uint32_t memoryTypeIndex,
VkMemoryPropertyFlags *pFlags);
VkResult MapMemory(VmaAllocator allocator, VmaAllocation allocation, void **ppData);
void UnmapMemory(VmaAllocator allocator, VmaAllocation allocation);
void FlushAllocation(VmaAllocator allocator,
VmaAllocation allocation,
VkDeviceSize offset,
VkDeviceSize size);
void InvalidateAllocation(VmaAllocator allocator,
VmaAllocation allocation,
VkDeviceSize offset,
VkDeviceSize size);
void BuildStatsString(VmaAllocator allocator, char **statsString, VkBool32 detailedMap);
void FreeStatsString(VmaAllocator allocator, char *statsString);
// VMA virtual block
VkResult CreateVirtualBlock(VkDeviceSize size,
VirtualBlockCreateFlags flags,
VmaVirtualBlock *pVirtualBlock);
void DestroyVirtualBlock(VmaVirtualBlock virtualBlock);
VkResult VirtualAllocate(VmaVirtualBlock virtualBlock,
VkDeviceSize size,
VkDeviceSize alignment,
VkDeviceSize *pOffset);
void VirtualFree(VmaVirtualBlock virtualBlock, VkDeviceSize offset);
VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock);
void GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,
VkDeviceSize offset,
VkDeviceSize *sizeOut,
void **pUserDataOut);
void ClearVirtualBlock(VmaVirtualBlock virtualBlock);
void SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,
VkDeviceSize offset,
void *pUserData);
void CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, StatInfo *pStatInfo);
void BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,
char **ppStatsString,
VkBool32 detailedMap);
void FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock, char *pStatsString);
} // namespace vma
#endif // LIBANGLE_RENDERER_VULKAN_VK_MEM_ALLOC_WRAPPER_H_