#define MSP_GL_VULKAN_MEMORYALLOCATOR_H_
#include <vector>
+#include <msp/core/noncopyable.h>
#include <msp/graphics/vulkancontext.h>
#include "handles.h"
STREAMING_MEMORY
};
-class MemoryAllocator
+class MemoryAllocator: public NonCopyable
{
private:
- struct Allocation
+ enum BlockType
+ {
+ UNDECIDED,
+ BUFFER,
+ IMAGE
+ };
+
+ struct Pool
{
- VkDeviceMemory memory = 0;
MemoryType type = UNKNOWN_MEMORY;
+ std::vector<unsigned> free_blocks;
+ int largest_free_buffer = -1;
+ int largest_free_image = -1;
+ bool can_consolidate = false;
+ };
+
+ struct Region
+ {
+ int pool = -1;
+ bool direct = false;
+ VkDeviceMemory memory = 0;
std::size_t size = 0;
void *mapped_address = 0;
+ unsigned map_count = 0;
+ };
+
+ struct Block
+ {
+ int region = -1;
+ bool allocated = false;
+ BlockType type = UNDECIDED;
+ std::size_t offset = 0;
+ std::size_t size = 0;
+ int prev = -1;
+ int next = -1;
};
Device &device;
VkPhysicalDevice phys_device;
- std::vector<MemoryType> memory_types;
- std::vector<Allocation> allocations;
+ std::size_t total_device_memory = 0;
+ std::size_t default_region_size = 0;
+ std::size_t direct_alloc_threshold = 0;
+ std::size_t min_alignment = 256;
+ std::size_t buffer_image_granularity = 131072;
+ std::vector<Pool> pools;
+ std::vector<Region> regions;
+ std::vector<Block> blocks;
public:
MemoryAllocator(Device &);
+ ~MemoryAllocator();
private:
- unsigned find_memory_type_index(unsigned, MemoryType);
- unsigned allocate(std::size_t, unsigned, MemoryType);
- Allocation &get_allocation(unsigned);
- const Allocation &get_allocation(unsigned) const;
+ unsigned find_memory_pool(unsigned, MemoryType) const;
+ unsigned create_region(unsigned, size_t, bool);
+ std::vector<unsigned>::iterator lower_bound_by_size(std::vector<unsigned> &, std::size_t) const;
+ std::size_t get_alloc_offset(const Block &, std::size_t, std::size_t, BlockType) const;
+ void update_largest_free(Pool &);
+ unsigned allocate(std::size_t, std::size_t, unsigned, MemoryType, BlockType);
+ unsigned split_block(unsigned, std::size_t);
+ void consolidate(unsigned);
+ void merge_block_with_next(unsigned);
public:
unsigned allocate(VkBuffer, MemoryType);
unsigned allocate(VkImage, MemoryType);
void release(unsigned);
- std::size_t get_allocation_size(unsigned) const;
+ void *map(unsigned);
+ void unmap(unsigned);
- void *map(unsigned, std::size_t, std::size_t);
- void unmap(void *);
+ std::string get_debug() const;
};
} // namespace GL