class VulkanMemoryPool {
public:
VulkanMemoryPool(vk::Device device, vk::PhysicalDevice physical_device,
vk::DeviceSize block_size, uint32_t memory_type_index)
: device(device), block_size(block_size), memory_type_index(memory_type_index) {
allocate_new_block();
}
~VulkanMemoryPool() {
for (auto& block : memory_blocks) {
device.freeMemory(block.memory);
}
}
struct Allocation {
vk::DeviceMemory memory;
vk::DeviceSize offset;
vk::DeviceSize size;
};
Allocation allocate(vk::DeviceSize size, vk::DeviceSize alignment) {
// Find a block with enough space
for (auto& block : memory_blocks) {
vk::DeviceSize aligned_offset = align(block.next_offset, alignment);
if (aligned_offset + size <= block_size) {
Allocation alloc;
alloc.memory = block.memory;
alloc.offset = aligned_offset;
alloc.size = size;
block.next_offset = aligned_offset + size;
return alloc;
}
}
// No block has enough space, allocate a new one
allocate_new_block();
return allocate(size, alignment); // Try again with the new block
}
private:
struct MemoryBlock {
vk::DeviceMemory memory;
vk::DeviceSize next_offset = 0;
};
void allocate_new_block() {
vk::MemoryAllocateInfo alloc_info;
alloc_info.setAllocationSize(block_size);
alloc_info.setMemoryTypeIndex(memory_type_index);
MemoryBlock block;
block.memory = device.allocateMemory(alloc_info);
block.next_offset = 0;
memory_blocks.push_back(block);
}
vk::DeviceSize align(vk::DeviceSize offset, vk::DeviceSize alignment) {
return (offset + alignment - 1) & ~(alignment - 1);
}
vk::Device device;
vk::DeviceSize block_size;
uint32_t memory_type_index;
std::vector<MemoryBlock> memory_blocks;
};