VulkanMemoryAllocator
VulkanMemoryAllocator copied to clipboard
do not create a dummy buffer and destroy when call vmaFindMemoryTypeIndexForBufferInfo
we saw everytime call vmaFindMemoryTypeIndexForBufferInfo, it take quite a few cpu cycles to do the following
"// Must create a dummy buffer to query :( VkBuffer hBuffer = VK_NULL_HANDLE; res = funcs->vkCreateBuffer( hDev, pBufferCreateInfo, allocator->GetAllocationCallbacks(), &hBuffer); if(res == VK_SUCCESS) { VkMemoryRequirements memReq = {}; funcs->vkGetBufferMemoryRequirements(hDev, hBuffer, &memReq);
res = allocator->FindMemoryTypeIndex(
memReq.memoryTypeBits, pAllocationCreateInfo,
VmaBufferImageUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5), pMemoryTypeIndex);
funcs->vkDestroyBuffer(
hDev, hBuffer, allocator->GetAllocationCallbacks());
}"
according to the spec. "The memoryTypeBits member is identical for all VkBuffer objects created with the same value for the flags and usage members in the VkBufferCreateInfo structure and the handleTypes member of the VkExternalMemoryBufferCreateInfo structure passed to vkCreateBuffer. Further, if usage1 and usage2 of type VkBufferUsageFlags are such that the bits set in usage2 are a subset of the bits set in usage1, and they have the same flags and VkExternalMemoryBufferCreateInfo::handleTypes, then the bits set in memoryTypeBits returned for usage1 must be a subset of the bits set in memoryTypeBits returned for usage2, for all values of flags." it looks the returned memoryTypeBit only affected by flags and usage and external buffer type. can we create a cache to avoid everytime create a dummy buffer.
Thank you for this suggestion.
The problem doesn't occur if you use Vulkan 1.3 or VK_KHR_maintenance4 extension (and inform VMA library about it during library initialization), because then function vmaFindMemoryTypeIndexForBufferInfo can use a new Vulkan function vkGetDeviceBufferMemoryRequirements. Can you enable Vulkan 1.3 or this extension in your project?
Implementing a cache for recently used buffer/image creation parameters is a good idea that may be implemented in the future.
currently we can not update the version to 1.3. since we have so many device running on vulkan 1.1. it will be perfect, if can fix this issue. thanks
@adam-sawicki-a Could you maybe explain a little what you mean with this? I don't understand:
Implementing a cache for recently used buffer/image creation parameters is a good idea that may be implemented in the future.
Overall, I don't think this is a major problem, because multiple solutions exist:
- Use Vulkan 1.3 or VK_KHR_maintenance4 if possible.
- Avoid using
vmaFindMemoryTypeIndexForBufferInfoand use recommended functionsvmaCreateBuffer,vmaCreateImageinstead, which are not affected by this problem because they query for memory requirements of the real buffer/image that we actually wanted to create. - If you need to call
vmaFindMemoryTypeIndexForBufferInfo, call it once and reuse the returnedmemoryTypeIndex.
But I can imagine implementing a cache for a few recently used VkBufferCreateInfo parameters and returned memoryTypeIndex. I would rather see it as a fixed-size array (e.g. 8 elements) of recently used parameters, without employing more complex data structures like a hash table.
Note that it can only work with buffers and not images. Images are guaranteed to have reliable returned memoryTypeIndex or alignment for same parameters only starting from maintenance4 which also provides vkGetDeviceImageMemoryRequirements, so we don't need to create a dummy resource anyway. Without it, the implementation may return different data for every image, and I remember an old AMD driver really returning different sizes for subsequent images with exactly the same parameters.