Optionally support vulkan_memory_allocator 3.x

Incompatible API is guarded behind a new define, ANGLE_VMA_VERSION.

This allows a soft migration for Chromium and Fuchsia, while allowing
clients like Flutter to roll to a new version that is compatible with
its revision of Skia.

Bug: chromium:1332566
Change-Id: I68cafde13e50445aa8eea2f18203143659a1c627
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3688835
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Dan Field <dnfield@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Dan Field 2022-06-03 09:22:41 -07:00 коммит произвёл Angle LUCI CQ
Родитель f6517f3078
Коммит 4b9eb4bace
9 изменённых файлов: 101 добавлений и 24 удалений

Просмотреть файл

@ -110,7 +110,17 @@ config("internal_config") {
"src",
]
defines = []
# Handle breaking changes in VulkanMemoryAllocator.
angle_vma_version_define = "ANGLE_VMA_VERSION="
if (defined(angle_vma_version)) {
angle_vma_version_define += angle_vma_version
} else {
# Default to 2.3.0. This can be bumped and include guards removed when all
# clients have migrated to 3.x.
angle_vma_version_define += 2003000
}
defines = [ angle_vma_version_define ]
if (is_win) {
defines += [ "ANGLE_IS_WIN" ]

Просмотреть файл

@ -8,6 +8,11 @@ angle_root = "//"
# True if ANGLE can access build/, testing/ and other Chrome folders.
angle_has_build = true
# Declares the maximum supported VulkanMemoryAllocator version by the client
# in format AAABBBCCC, where AAA = major, BBB = minor, CCC = patch.
# The VulkanMemoryAllocator version may be found in its CHANGELOG.md.
angle_vma_version = 2003000
# Overrides for ANGLE's dependencies
angle_abseil_cpp_dir = "//third_party/abseil-cpp"
angle_glslang_dir = "//third_party/vulkan-deps/glslang/src"

Просмотреть файл

@ -266,6 +266,7 @@ angle_source_set("angle_vk_mem_alloc_wrapper") {
"$angle_root/src/common/vulkan:angle_vulkan_headers",
"$angle_vulkan_memory_allocator_dir",
]
include_dirs = [ "$angle_vulkan_memory_allocator_dir/include" ]
configs += [ "$angle_root:angle_no_cfi_unrelated_cast" ]
sources = [
"vk_mem_alloc_wrapper.cpp",
@ -277,6 +278,7 @@ angle_source_set("angle_vk_mem_alloc_wrapper") {
"-Wno-missing-field-initializers",
"-Wno-suggest-destructor-override",
"-Wno-suggest-override",
"-Wno-inconsistent-missing-destructor-override",
]
}
}

Просмотреть файл

@ -2990,6 +2990,7 @@ angle::Result BufferPool::allocateBuffer(Context *context,
BufferSuballocation *suballocation)
{
ASSERT(alignment);
VmaVirtualAllocation allocation;
VkDeviceSize offset;
VkDeviceSize alignedSize = roundUp(sizeInBytes, alignment);
@ -3048,9 +3049,9 @@ angle::Result BufferPool::allocateBuffer(Context *context,
continue;
}
if (block->allocate(alignedSize, alignment, &offset) == VK_SUCCESS)
if (block->allocate(alignedSize, alignment, &allocation, &offset) == VK_SUCCESS)
{
suballocation->init(context->getDevice(), block.get(), offset, alignedSize);
suballocation->init(context->getDevice(), block.get(), allocation, offset, alignedSize);
return angle::Result::Continue;
}
++iter;
@ -3068,8 +3069,8 @@ angle::Result BufferPool::allocateBuffer(Context *context,
}
else
{
ANGLE_VK_TRY(context, block->allocate(alignedSize, alignment, &offset));
suballocation->init(context->getDevice(), block.get(), offset, alignedSize);
ANGLE_VK_TRY(context, block->allocate(alignedSize, alignment, &allocation, &offset));
suballocation->init(context->getDevice(), block.get(), allocation, offset, alignedSize);
mBufferBlocks.push_back(std::move(block));
mEmptyBufferBlocks.pop_back();
mNumberOfNewBuffersNeededSinceLastPrune++;
@ -3082,9 +3083,10 @@ angle::Result BufferPool::allocateBuffer(Context *context,
// Sub-allocate from the bufferBlock.
std::unique_ptr<BufferBlock> &block = mBufferBlocks.back();
ANGLE_VK_CHECK(context, block->allocate(alignedSize, alignment, &offset) == VK_SUCCESS,
ANGLE_VK_CHECK(context,
block->allocate(alignedSize, alignment, &allocation, &offset) == VK_SUCCESS,
VK_ERROR_OUT_OF_DEVICE_MEMORY);
suballocation->init(context->getDevice(), block.get(), offset, alignedSize);
suballocation->init(context->getDevice(), block.get(), allocation, offset, alignedSize);
mNumberOfNewBuffersNeededSinceLastPrune++;
return angle::Result::Continue;

Просмотреть файл

@ -18,7 +18,9 @@ namespace vma
static_cast<uint32_t>(VMA_VIRTUAL_BLOCK_CREATE_##x##_ALGORITHM_BIT), \
"VMA enum mismatch")
VALIDATE_BLOCK_CREATE_FLAG_BITS(LINEAR);
#if ANGLE_VMA_VERSION < 3000000
VALIDATE_BLOCK_CREATE_FLAG_BITS(BUDDY);
#endif // ANGLE_VMA_VERSION < 3000000
VkResult InitAllocator(VkPhysicalDevice physicalDevice,
VkDevice device,
@ -81,17 +83,21 @@ void DestroyAllocator(VmaAllocator allocator)
VkResult CreatePool(VmaAllocator allocator,
uint32_t memoryTypeIndex,
#if ANGLE_VMA_VERSION < 3000000
bool buddyAlgorithm,
#endif // ANGLE_VMA_VERSION < 3000000
VkDeviceSize blockSize,
VmaPool *pPool)
{
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.memoryTypeIndex = memoryTypeIndex;
poolCreateInfo.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT;
#if ANGLE_VMA_VERSION < 3000000
if (buddyAlgorithm)
{
poolCreateInfo.flags |= VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT;
}
#endif
poolCreateInfo.blockSize = blockSize;
poolCreateInfo.maxBlockCount = -1; // unlimited
return vmaCreatePool(allocator, &poolCreateInfo, pPool);
@ -208,18 +214,27 @@ void DestroyVirtualBlock(VmaVirtualBlock virtualBlock)
VkResult VirtualAllocate(VmaVirtualBlock virtualBlock,
VkDeviceSize size,
VkDeviceSize alignment,
VmaVirtualAllocation *pAllocation,
VkDeviceSize *pOffset)
{
VmaVirtualAllocationCreateInfo createInfo = {};
createInfo.size = size;
createInfo.alignment = alignment;
createInfo.flags = 0;
#if ANGLE_VMA_VERSION < 3000000
return vmaVirtualAllocate(virtualBlock, &createInfo, pOffset);
#else
return vmaVirtualAllocate(virtualBlock, &createInfo, pAllocation, pOffset);
#endif // ANGLE_VMA_VERSION < 3000000
}
void VirtualFree(VmaVirtualBlock virtualBlock, VkDeviceSize offset)
void VirtualFree(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, VkDeviceSize offset)
{
#if ANGLE_VMA_VERSION < 3000000
vmaVirtualFree(virtualBlock, offset);
#else
vmaVirtualFree(virtualBlock, allocation);
#endif // ANGLE_VMA_VERSION < 3000000
}
VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)
@ -228,12 +243,17 @@ VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)
}
void GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,
VmaVirtualAllocation allocation,
VkDeviceSize offset,
VkDeviceSize *sizeOut,
void **pUserDataOut)
{
VmaVirtualAllocationInfo virtualAllocInfo = {};
#if ANGLE_VMA_VERSION < 3000000
vmaGetVirtualAllocationInfo(virtualBlock, offset, &virtualAllocInfo);
#else
vmaGetVirtualAllocationInfo(virtualBlock, allocation, &virtualAllocInfo);
#endif // ANGLE_VMA_VERSION < 3000000
*sizeOut = virtualAllocInfo.size;
*pUserDataOut = virtualAllocInfo.pUserData;
}
@ -244,15 +264,25 @@ void ClearVirtualBlock(VmaVirtualBlock virtualBlock)
}
void SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,
VmaVirtualAllocation allocation,
VkDeviceSize offset,
void *pUserData)
{
#if ANGLE_VMA_VERSION < 3000000
vmaSetVirtualAllocationUserData(virtualBlock, offset, pUserData);
#else
vmaSetVirtualAllocationUserData(virtualBlock, allocation, pUserData);
#endif // ANGLE_VMA_VERSION < 3000000
}
void CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, StatInfo *pStatInfo)
{
#if ANGLE_VMA_VERSION < 3000000
vmaCalculateVirtualBlockStats(virtualBlock, reinterpret_cast<VmaStatInfo *>(pStatInfo));
#else
vmaCalculateVirtualBlockStatistics(virtualBlock,
reinterpret_cast<VmaDetailedStatistics *>(pStatInfo));
#endif // ANGLE_VMA_VERSION < 3000000
}
void BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,

Просмотреть файл

@ -15,6 +15,7 @@
VK_DEFINE_HANDLE(VmaAllocator)
VK_DEFINE_HANDLE(VmaAllocation)
VK_DEFINE_HANDLE(VmaPool)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VmaVirtualAllocation)
VK_DEFINE_HANDLE(VmaVirtualBlock)
namespace vma
@ -54,7 +55,9 @@ void DestroyAllocator(VmaAllocator allocator);
VkResult CreatePool(VmaAllocator allocator,
uint32_t memoryTypeIndex,
#if ANGLE_VMA_VERSION < 3000000
bool buddyAlgorithm,
#endif // ANGLE_VMA_VERSION < 3000000
VkDeviceSize blockSize,
VmaPool *pPool);
void DestroyPool(VmaAllocator allocator, VmaPool pool);
@ -106,10 +109,14 @@ void DestroyVirtualBlock(VmaVirtualBlock virtualBlock);
VkResult VirtualAllocate(VmaVirtualBlock virtualBlock,
VkDeviceSize size,
VkDeviceSize alignment,
VmaVirtualAllocation *pAllocation,
VkDeviceSize *pOffset);
void VirtualFree(VmaVirtualBlock virtualBlock, VkDeviceSize offset);
void VirtualFree(VmaVirtualBlock virtualBlock,
VmaVirtualAllocation allocation,
VkDeviceSize offset);
VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock);
void GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,
VmaVirtualAllocation allocation,
VkDeviceSize offset,
VkDeviceSize *sizeOut,
void **pUserDataOut);

Просмотреть файл

@ -1787,10 +1787,10 @@ void BufferBlock::unmap(const VkDevice device)
mMappedMemory = nullptr;
}
void BufferBlock::free(VkDeviceSize offset)
void BufferBlock::free(VmaVirtualAllocation allocation, VkDeviceSize offset)
{
std::lock_guard<ConditionalMutex> lock(mVirtualBlockMutex);
mVirtualBlock.free(offset);
mVirtualBlock.free(allocation, offset);
}
int32_t BufferBlock::getAndIncrementEmptyCounter()

Просмотреть файл

@ -936,8 +936,11 @@ class BufferBlock final : angle::NonCopyable
VkMemoryPropertyFlags getMemoryPropertyFlags() const;
VkDeviceSize getMemorySize() const;
VkResult allocate(VkDeviceSize size, VkDeviceSize alignment, VkDeviceSize *offsetOut);
void free(VkDeviceSize offset);
VkResult allocate(VkDeviceSize size,
VkDeviceSize alignment,
VmaVirtualAllocation *allocationOut,
VkDeviceSize *offsetOut);
void free(VmaVirtualAllocation allocation, VkDeviceSize offset);
VkBool32 isEmpty();
bool hasVirtualBlock() const { return mVirtualBlock.valid(); }
@ -983,7 +986,11 @@ class BufferSuballocation final : angle::NonCopyable
void destroy(RendererVk *renderer);
void init(VkDevice device, BufferBlock *block, VkDeviceSize offset, VkDeviceSize size);
void init(VkDevice device,
BufferBlock *block,
VmaVirtualAllocation allocation,
VkDeviceSize offset,
VkDeviceSize size);
void initWithEntireBuffer(Context *context,
Buffer &buffer,
DeviceMemory &deviceMemory,
@ -1017,6 +1024,7 @@ class BufferSuballocation final : angle::NonCopyable
void setOffsetAndSize(VkDeviceSize offset, VkDeviceSize size);
BufferBlock *mBufferBlock;
VmaVirtualAllocation mAllocation;
VkDeviceSize mOffset;
VkDeviceSize mSize;
};
@ -1061,16 +1069,17 @@ ANGLE_INLINE uint8_t *BufferBlock::getMappedMemory() const
ANGLE_INLINE VkResult BufferBlock::allocate(VkDeviceSize size,
VkDeviceSize alignment,
VmaVirtualAllocation *allocationOut,
VkDeviceSize *offsetOut)
{
std::lock_guard<ConditionalMutex> lock(mVirtualBlockMutex);
mCountRemainsEmpty = 0;
return mVirtualBlock.allocate(size, alignment, offsetOut);
return mVirtualBlock.allocate(size, alignment, allocationOut, offsetOut);
}
// BufferSuballocation implementation.
ANGLE_INLINE BufferSuballocation::BufferSuballocation()
: mBufferBlock(nullptr), mOffset(0), mSize(0)
: mBufferBlock(nullptr), mAllocation(VK_NULL_HANDLE), mOffset(0), mSize(0)
{}
ANGLE_INLINE BufferSuballocation::BufferSuballocation(BufferSuballocation &&other)
@ -1083,6 +1092,7 @@ ANGLE_INLINE BufferSuballocation &BufferSuballocation::operator=(BufferSuballoca
{
std::swap(mBufferBlock, other.mBufferBlock);
std::swap(mSize, other.mSize);
std::swap(mAllocation, other.mAllocation);
std::swap(mOffset, other.mOffset);
return *this;
}
@ -1099,7 +1109,7 @@ ANGLE_INLINE void BufferSuballocation::destroy(RendererVk *renderer)
ASSERT(mBufferBlock);
if (mBufferBlock->hasVirtualBlock())
{
mBufferBlock->free(mOffset);
mBufferBlock->free(mAllocation, mOffset);
mBufferBlock = nullptr;
}
else
@ -1110,20 +1120,26 @@ ANGLE_INLINE void BufferSuballocation::destroy(RendererVk *renderer)
mBufferBlock->destroy(renderer);
SafeDelete(mBufferBlock);
}
mOffset = 0;
mSize = 0;
mAllocation = VK_NULL_HANDLE;
mOffset = 0;
mSize = 0;
}
}
ANGLE_INLINE void BufferSuballocation::init(VkDevice device,
BufferBlock *block,
VmaVirtualAllocation allocation,
VkDeviceSize offset,
VkDeviceSize size)
{
ASSERT(!valid());
ASSERT(block != nullptr);
#if ANGLE_VMA_VERSION >= 3000000
ASSERT(allocation != VK_NULL_HANDLE);
#endif // ANGLE_VMA_VERSION >= 3000000
ASSERT(offset != VK_WHOLE_SIZE);
mBufferBlock = block;
mAllocation = allocation;
mOffset = offset;
mSize = size;
}
@ -1141,6 +1157,7 @@ ANGLE_INLINE void BufferSuballocation::initWithEntireBuffer(
block->initWithoutVirtualBlock(context, buffer, deviceMemory, memoryPropertyFlags, size);
mBufferBlock = block.release();
mAllocation = VK_NULL_HANDLE;
mOffset = 0;
mSize = mBufferBlock->getMemorySize();
}

Просмотреть файл

@ -684,8 +684,11 @@ class VirtualBlock final : public WrappedObject<VirtualBlock, VmaVirtualBlock>
void destroy(VkDevice device);
VkResult init(VkDevice device, vma::VirtualBlockCreateFlags flags, VkDeviceSize size);
VkResult allocate(VkDeviceSize size, VkDeviceSize alignment, VkDeviceSize *offsetOut);
void free(VkDeviceSize offset);
VkResult allocate(VkDeviceSize size,
VkDeviceSize alignment,
VmaVirtualAllocation *allocationOut,
VkDeviceSize *offsetOut);
void free(VmaVirtualAllocation allocation, VkDeviceSize offset);
void calculateStats(vma::StatInfo *pStatInfo) const;
};
@ -1994,14 +1997,15 @@ ANGLE_INLINE VkResult VirtualBlock::init(VkDevice device,
ANGLE_INLINE VkResult VirtualBlock::allocate(VkDeviceSize size,
VkDeviceSize alignment,
VmaVirtualAllocation *allocationOut,
VkDeviceSize *offsetOut)
{
return vma::VirtualAllocate(mHandle, size, alignment, offsetOut);
return vma::VirtualAllocate(mHandle, size, alignment, allocationOut, offsetOut);
}
ANGLE_INLINE void VirtualBlock::free(VkDeviceSize offset)
ANGLE_INLINE void VirtualBlock::free(VmaVirtualAllocation allocation, VkDeviceSize offset)
{
vma::VirtualFree(mHandle, offset);
vma::VirtualFree(mHandle, allocation, offset);
}
ANGLE_INLINE void VirtualBlock::calculateStats(vma::StatInfo *pStatInfo) const