]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/memoryallocator.h
Overhaul the Vulkan backend's memory allocator
[libs/gl.git] / source / backends / vulkan / memoryallocator.h
index 230f21a202126d176034f576981426eddab9f281..272f54e0ed79d87cd73180702558a5c0ee507b09 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_VULKAN_MEMORYALLOCATOR_H_
 
 #include <vector>
+#include <msp/core/noncopyable.h>
 #include <msp/graphics/vulkancontext.h>
 #include "handles.h"
 
@@ -18,28 +19,58 @@ enum MemoryType
        STREAMING_MEMORY
 };
 
-class MemoryAllocator
+class MemoryAllocator: public NonCopyable
 {
 private:
-       struct Allocation
+       struct Pool
        {
-               VkDeviceMemory memory = 0;
                MemoryType type = UNKNOWN_MEMORY;
+               std::vector<unsigned> free_blocks;
+               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;
+               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::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);
+       unsigned find_memory_pool(unsigned, MemoryType);
+       unsigned create_region(unsigned, size_t, bool);
+       std::vector<unsigned>::iterator lower_bound_by_size(std::vector<unsigned> &, std::size_t);
+       unsigned allocate(std::size_t, std::size_t, unsigned, MemoryType);
+       unsigned split_block(unsigned, std::size_t);
+       void consolidate(unsigned);
+       void merge_block_with_next(unsigned);
 
 public:
        unsigned allocate(VkBuffer, MemoryType);