blob: 49128c833be8775a57d46d3c2fee7ff401a19612 [file] [log] [blame]
//
// 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.cpp:
// Hides VMA functions so we can use separate warning sets.
//
#include "vk_mem_alloc_wrapper.h"
#include <vk_mem_alloc.h>
namespace vma
{
#define VALIDATE_BLOCK_CREATE_FLAG_BITS(x) \
static_assert(static_cast<uint32_t>(x) == \
static_cast<uint32_t>(VMA_VIRTUAL_BLOCK_CREATE_##x##_ALGORITHM_BIT), \
"VMA enum mismatch")
VALIDATE_BLOCK_CREATE_FLAG_BITS(LINEAR);
VALIDATE_BLOCK_CREATE_FLAG_BITS(BUDDY);
VkResult InitAllocator(VkPhysicalDevice physicalDevice,
VkDevice device,
VkInstance instance,
uint32_t apiVersion,
VkDeviceSize preferredLargeHeapBlockSize,
VmaAllocator *pAllocator)
{
VmaVulkanFunctions funcs = {};
funcs.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties;
funcs.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
funcs.vkAllocateMemory = vkAllocateMemory;
funcs.vkFreeMemory = vkFreeMemory;
funcs.vkMapMemory = vkMapMemory;
funcs.vkUnmapMemory = vkUnmapMemory;
funcs.vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges;
funcs.vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges;
funcs.vkBindBufferMemory = vkBindBufferMemory;
funcs.vkBindImageMemory = vkBindImageMemory;
funcs.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements;
funcs.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements;
funcs.vkCreateBuffer = vkCreateBuffer;
funcs.vkDestroyBuffer = vkDestroyBuffer;
funcs.vkCreateImage = vkCreateImage;
funcs.vkDestroyImage = vkDestroyImage;
funcs.vkCmdCopyBuffer = vkCmdCopyBuffer;
{
#if !defined(ANGLE_SHARED_LIBVULKAN)
// When the vulkan-loader is statically linked, we need to use the extension
// functions defined in ANGLE's rx namespace. When it's dynamically linked
// with volk, this will default to the function definitions with no namespace
using rx::vkBindBufferMemory2KHR;
using rx::vkBindImageMemory2KHR;
using rx::vkGetBufferMemoryRequirements2KHR;
using rx::vkGetImageMemoryRequirements2KHR;
using rx::vkGetPhysicalDeviceMemoryProperties2KHR;
#endif // !defined(ANGLE_SHARED_LIBVULKAN)
funcs.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2KHR;
funcs.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2KHR;
funcs.vkBindBufferMemory2KHR = vkBindBufferMemory2KHR;
funcs.vkBindImageMemory2KHR = vkBindImageMemory2KHR;
funcs.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2KHR;
}
VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.physicalDevice = physicalDevice;
allocatorInfo.device = device;
allocatorInfo.instance = instance;
allocatorInfo.pVulkanFunctions = &funcs;
allocatorInfo.vulkanApiVersion = apiVersion;
allocatorInfo.preferredLargeHeapBlockSize = preferredLargeHeapBlockSize;
return vmaCreateAllocator(&allocatorInfo, pAllocator);
}
void DestroyAllocator(VmaAllocator allocator)
{
vmaDestroyAllocator(allocator);
}
VkResult CreatePool(VmaAllocator allocator,
uint32_t memoryTypeIndex,
bool buddyAlgorithm,
VkDeviceSize blockSize,
VmaPool *pPool)
{
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.memoryTypeIndex = memoryTypeIndex;
poolCreateInfo.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT;
if (buddyAlgorithm)
{
poolCreateInfo.flags |= VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT;
}
poolCreateInfo.blockSize = blockSize;
poolCreateInfo.maxBlockCount = -1; // unlimited
return vmaCreatePool(allocator, &poolCreateInfo, pPool);
}
void DestroyPool(VmaAllocator allocator, VmaPool pool)
{
vmaDestroyPool(allocator, pool);
}
void FreeMemory(VmaAllocator allocator, VmaAllocation allocation)
{
vmaFreeMemory(allocator, allocation);
}
VkResult CreateBuffer(VmaAllocator allocator,
const VkBufferCreateInfo *pBufferCreateInfo,
VkMemoryPropertyFlags requiredFlags,
VkMemoryPropertyFlags preferredFlags,
bool persistentlyMapped,
uint32_t *pMemoryTypeIndexOut,
VkBuffer *pBuffer,
VmaAllocation *pAllocation)
{
VkResult result;
VmaAllocationCreateInfo allocationCreateInfo = {};
allocationCreateInfo.requiredFlags = requiredFlags;
allocationCreateInfo.preferredFlags = preferredFlags;
allocationCreateInfo.flags = (persistentlyMapped) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
VmaAllocationInfo allocationInfo = {};
result = vmaCreateBuffer(allocator, pBufferCreateInfo, &allocationCreateInfo, pBuffer,
pAllocation, &allocationInfo);
*pMemoryTypeIndexOut = allocationInfo.memoryType;
return result;
}
VkResult FindMemoryTypeIndexForBufferInfo(VmaAllocator allocator,
const VkBufferCreateInfo *pBufferCreateInfo,
VkMemoryPropertyFlags requiredFlags,
VkMemoryPropertyFlags preferredFlags,
bool persistentlyMappedBuffers,
uint32_t *pMemoryTypeIndexOut)
{
VmaAllocationCreateInfo allocationCreateInfo = {};
allocationCreateInfo.requiredFlags = requiredFlags;
allocationCreateInfo.preferredFlags = preferredFlags;
allocationCreateInfo.flags = (persistentlyMappedBuffers) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;
return vmaFindMemoryTypeIndexForBufferInfo(allocator, pBufferCreateInfo, &allocationCreateInfo,
pMemoryTypeIndexOut);
}
void GetMemoryTypeProperties(VmaAllocator allocator,
uint32_t memoryTypeIndex,
VkMemoryPropertyFlags *pFlags)
{
vmaGetMemoryTypeProperties(allocator, memoryTypeIndex, pFlags);
}
VkResult MapMemory(VmaAllocator allocator, VmaAllocation allocation, void **ppData)
{
return vmaMapMemory(allocator, allocation, ppData);
}
void UnmapMemory(VmaAllocator allocator, VmaAllocation allocation)
{
return vmaUnmapMemory(allocator, allocation);
}
void FlushAllocation(VmaAllocator allocator,
VmaAllocation allocation,
VkDeviceSize offset,
VkDeviceSize size)
{
vmaFlushAllocation(allocator, allocation, offset, size);
}
void InvalidateAllocation(VmaAllocator allocator,
VmaAllocation allocation,
VkDeviceSize offset,
VkDeviceSize size)
{
vmaInvalidateAllocation(allocator, allocation, offset, size);
}
void BuildStatsString(VmaAllocator allocator, char **statsString, VkBool32 detailedMap)
{
vmaBuildStatsString(allocator, statsString, detailedMap);
}
void FreeStatsString(VmaAllocator allocator, char *statsString)
{
vmaFreeStatsString(allocator, statsString);
}
// VmaVirtualBlock implementation
VkResult CreateVirtualBlock(VkDeviceSize size,
VirtualBlockCreateFlags flags,
VmaVirtualBlock *pVirtualBlock)
{
VmaVirtualBlockCreateInfo virtualBlockCreateInfo = {};
virtualBlockCreateInfo.size = size;
virtualBlockCreateInfo.flags = (VmaVirtualBlockCreateFlagBits)flags;
return vmaCreateVirtualBlock(&virtualBlockCreateInfo, pVirtualBlock);
}
void DestroyVirtualBlock(VmaVirtualBlock virtualBlock)
{
vmaDestroyVirtualBlock(virtualBlock);
}
VkResult VirtualAllocate(VmaVirtualBlock virtualBlock,
VkDeviceSize size,
VkDeviceSize alignment,
VkDeviceSize *pOffset)
{
VmaVirtualAllocationCreateInfo createInfo = {};
createInfo.size = size;
createInfo.alignment = alignment;
createInfo.flags = 0;
return vmaVirtualAllocate(virtualBlock, &createInfo, pOffset);
}
void VirtualFree(VmaVirtualBlock virtualBlock, VkDeviceSize offset)
{
vmaVirtualFree(virtualBlock, offset);
}
VkBool32 IsVirtualBlockEmpty(VmaVirtualBlock virtualBlock)
{
return vmaIsVirtualBlockEmpty(virtualBlock);
}
void GetVirtualAllocationInfo(VmaVirtualBlock virtualBlock,
VkDeviceSize offset,
VkDeviceSize *sizeOut,
void **pUserDataOut)
{
VmaVirtualAllocationInfo virtualAllocInfo = {};
vmaGetVirtualAllocationInfo(virtualBlock, offset, &virtualAllocInfo);
*sizeOut = virtualAllocInfo.size;
*pUserDataOut = virtualAllocInfo.pUserData;
}
void ClearVirtualBlock(VmaVirtualBlock virtualBlock)
{
vmaClearVirtualBlock(virtualBlock);
}
void SetVirtualAllocationUserData(VmaVirtualBlock virtualBlock,
VkDeviceSize offset,
void *pUserData)
{
vmaSetVirtualAllocationUserData(virtualBlock, offset, pUserData);
}
void CalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, StatInfo *pStatInfo)
{
vmaCalculateVirtualBlockStats(virtualBlock, reinterpret_cast<VmaStatInfo *>(pStatInfo));
}
void BuildVirtualBlockStatsString(VmaVirtualBlock virtualBlock,
char **ppStatsString,
VkBool32 detailedMap)
{
vmaBuildVirtualBlockStatsString(virtualBlock, ppStatsString, detailedMap);
}
void FreeVirtualBlockStatsString(VmaVirtualBlock virtualBlock, char *pStatsString)
{
vmaFreeVirtualBlockStatsString(virtualBlock, pStatsString);
}
} // namespace vma