diff options
author | Pedro J. Estébanez <pedrojrulez@gmail.com> | 2022-02-24 12:47:34 +0100 |
---|---|---|
committer | Pedro J. Estébanez <pedrojrulez@gmail.com> | 2022-02-24 14:30:55 +0100 |
commit | 801741e7870a3e4f943a8628447c5eac74ecb2e3 (patch) | |
tree | 7007584f54a68979b8e51ae560fc2ed12d0b4f94 /drivers/vulkan | |
parent | 6a35864a6ddf84f97caeb6b3e830a4f4cfbd7082 (diff) |
vk_mem_alloc: Update to upstream + Adapt approach to small objects pooling
This updates VMA and instead of using the custom small pool approach from 4e6c9d3ae979f2eb0151cf581fe61d2f3194ea72, lazily creates pools for the relevant memory type indices, which doesn't require patching VMA.
Also, patches already merged upstream or not needed any longer are removed.
Diffstat (limited to 'drivers/vulkan')
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 62 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 3 |
2 files changed, 46 insertions, 19 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index cda8871f3e..2947a9b04e 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1335,8 +1335,13 @@ Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, allocInfo.requiredFlags = 0; allocInfo.preferredFlags = 0; allocInfo.memoryTypeBits = 0; - allocInfo.pool = p_size <= SMALL_ALLOCATION_MAX_SIZE ? small_allocs_pool : nullptr; + allocInfo.pool = nullptr; allocInfo.pUserData = nullptr; + if (p_size <= SMALL_ALLOCATION_MAX_SIZE) { + uint32_t mem_type_index = 0; + vmaFindMemoryTypeIndexForBufferInfo(allocator, &bufferInfo, &allocInfo, &mem_type_index); + allocInfo.pool = _find_or_create_small_allocs_pool(mem_type_index); + } VkResult err = vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &p_buffer->buffer, &p_buffer->allocation, nullptr); ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); @@ -1843,12 +1848,17 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T VmaAllocationCreateInfo allocInfo; allocInfo.flags = 0; - allocInfo.pool = image_size <= SMALL_ALLOCATION_MAX_SIZE ? small_allocs_pool : nullptr; + allocInfo.pool = nullptr; allocInfo.usage = p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT ? VMA_MEMORY_USAGE_CPU_ONLY : VMA_MEMORY_USAGE_GPU_ONLY; allocInfo.requiredFlags = 0; allocInfo.preferredFlags = 0; allocInfo.memoryTypeBits = 0; allocInfo.pUserData = nullptr; + if (image_size <= SMALL_ALLOCATION_MAX_SIZE) { + uint32_t mem_type_index = 0; + vmaFindMemoryTypeIndexForImageInfo(allocator, &image_create_info, &allocInfo, &mem_type_index); + allocInfo.pool = _find_or_create_small_allocs_pool(mem_type_index); + } Texture texture; @@ -8714,6 +8724,30 @@ void RenderingDeviceVulkan::sync() { local_device_processing = false; } +VmaPool RenderingDeviceVulkan::_find_or_create_small_allocs_pool(uint32_t p_mem_type_index) { + if (small_allocs_pools.has(p_mem_type_index)) { + return small_allocs_pools[p_mem_type_index]; + } + + print_verbose("Creating VMA small objects pool for memory type index " + itos(p_mem_type_index)); + + VmaPoolCreateInfo pci; + pci.memoryTypeIndex = p_mem_type_index; + pci.flags = 0; + pci.blockSize = 0; + pci.minBlockCount = 0; + pci.maxBlockCount = SIZE_MAX; + pci.priority = 0.5f; + pci.minAllocationAlignment = 0; + pci.pMemoryAllocateNext = nullptr; + VmaPool pool = VK_NULL_HANDLE; + VkResult res = vmaCreatePool(allocator, &pci, &pool); + small_allocs_pools[p_mem_type_index] = pool; // Don't try to create it again if failed the first time + ERR_FAIL_COND_V_MSG(res, pool, "vmaCreatePool failed with error " + itos(res) + "."); + + return pool; +} + void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { //free in dependency usage order, so nothing weird happens //pipelines @@ -8834,9 +8868,9 @@ uint64_t RenderingDeviceVulkan::get_memory_usage(MemoryType p_type) const { } else if (p_type == MEMORY_TEXTURES) { return image_memory; } else { - VmaStats stats; - vmaCalculateStats(allocator, &stats); - return stats.total.usedBytes; + VmaTotalStatistics stats; + vmaCalculateStatistics(allocator, &stats); + return stats.total.statistics.allocationBytes; } } @@ -8935,18 +8969,6 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de vmaCreateAllocator(&allocatorInfo, &allocator); } - { //create pool for small objects - VmaPoolCreateInfo pci; - pci.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT; - pci.blockSize = 0; - pci.minBlockCount = 0; - pci.maxBlockCount = SIZE_MAX; - pci.priority = 0.5f; - pci.minAllocationAlignment = 0; - pci.pMemoryAllocateNext = nullptr; - vmaCreatePool(allocator, &pci, &small_allocs_pool); - } - frames = memnew_arr(Frame, frame_count); frame = 0; //create setup and frame buffers @@ -9415,7 +9437,11 @@ void RenderingDeviceVulkan::finalize() { for (int i = 0; i < staging_buffer_blocks.size(); i++) { vmaDestroyBuffer(allocator, staging_buffer_blocks[i].buffer, staging_buffer_blocks[i].allocation); } - vmaDestroyPool(allocator, small_allocs_pool); + while (small_allocs_pools.size()) { + Map<uint32_t, VmaPool>::Element *E = small_allocs_pools.front(); + vmaDestroyPool(allocator, E->get()); + small_allocs_pools.erase(E); + } vmaDestroyAllocator(allocator); while (vertex_formats.size()) { diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 3e4327667b..126f6f8ad0 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -1016,7 +1016,8 @@ class RenderingDeviceVulkan : public RenderingDevice { void _free_pending_resources(int p_frame); VmaAllocator allocator = nullptr; - VmaPool small_allocs_pool = nullptr; + Map<uint32_t, VmaPool> small_allocs_pools; + VmaPool _find_or_create_small_allocs_pool(uint32_t p_mem_type_index); VulkanContext *context = nullptr; |