allocator.cpp

cross platform rendering playground

src/backend/vulkan/allocator.cpp

1.79 KB
#define VMA_IMPLEMENTATION
#define VMA_STATIC_VULKAN_FUNCTIONS  0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1

#include <vk_mem_alloc.h>

#include "backend/vulkan/vk_api.h"
#include "backend/vulkan/vk_conversion.h"
#include "core/logger.h"

namespace rhi {
using namespace vk;

bool create_memory_allocator(Device &device) {
    VEL_INFO("Creating GPU Memory Allocator...");
    VmaVulkanFunctions funcs{};
    funcs.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
    funcs.vkGetDeviceProcAddr = vkGetDeviceProcAddr;

    VmaAllocatorCreateInfo ci{};
    ci.instance = device.instance;
    ci.physicalDevice = device.physical;
    ci.device = device.logical;
    ci.vulkanApiVersion = VK_API_VERSION_1_3;
    ci.pVulkanFunctions = &funcs;
    ci.flags = VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT | VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
    VmaAllocator vk_allocator;
    if (vmaCreateAllocator(&ci, &vk_allocator) != VK_SUCCESS) {
        return false;
    }
    device.memory.allocator = vk_allocator;
    return true;
}

void destroy_memory_allocator(Device &device) {
    Memory mem = device.memory;
    VEL_INFO("Destroying GPU Memory Allocator...");
    if (mem.allocator != VK_NULL_HANDLE) {
        vmaDestroyAllocator(mem.allocator);
        mem.allocator = VK_NULL_HANDLE;
    }
}

rhi::MemoryStats memory_stats(Device &device) {
    rhi::MemoryStats out;
    if (device.memory.allocator == VK_NULL_HANDLE) {
        return out;
    }
    VmaTotalStatistics stats;
    vmaCalculateStatistics(device.memory.allocator, &stats);
    out.block_count = stats.total.statistics.blockCount;
    out.allocation_count = stats.total.statistics.allocationCount;
    out.allocation_bytes = stats.total.statistics.allocationBytes;
    out.used_bytes = stats.total.statistics.allocationBytes;
    return out;
}

} // namespace rhi