98 lines
2.8 KiB
C++
98 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include "forward.hpp"
|
|
#include <vector>
|
|
#include <optional>
|
|
#include <memory>
|
|
|
|
namespace tracy {
|
|
class VkCtx;
|
|
}
|
|
typedef tracy::VkCtx* TracyVkCtx;
|
|
namespace render::vk {
|
|
|
|
class Allocator {
|
|
private:
|
|
struct Allocation;
|
|
public:
|
|
Allocator(VkDevice, const PhysicalDeviceInfo&);
|
|
~Allocator();
|
|
|
|
struct memory_area {
|
|
VkDeviceMemory ref;
|
|
VkDeviceSize size;
|
|
VkDeviceSize offset;
|
|
void *ptr = nullptr;
|
|
|
|
void write(const void*, VkDeviceSize size, VkDeviceSize offset = 0);
|
|
void read(void*, VkDeviceSize size, VkDeviceSize offset = 0);
|
|
};
|
|
|
|
class MemoryDeleter {
|
|
public:
|
|
MemoryDeleter(Allocation *owner): owner(owner) { }
|
|
void operator()(memory_area *);
|
|
private:
|
|
Allocation *owner;
|
|
};
|
|
|
|
using memory_ptr = std::unique_ptr<memory_area, MemoryDeleter>;
|
|
|
|
memory_ptr allocate(VkMemoryRequirements, VkMemoryPropertyFlags);
|
|
bool deallocate(const memory_area&);
|
|
|
|
struct buffer_info {
|
|
VkBuffer buffer = nullptr;
|
|
VkDeviceSize offset = 0;
|
|
};
|
|
struct buffer_requirement {
|
|
VkDeviceSize size;
|
|
VkBufferUsageFlags usage;
|
|
const void *data = nullptr;
|
|
VkDeviceSize data_size = 0;
|
|
VkDeviceSize data_offset = 0;
|
|
};
|
|
memory_ptr createBuffer(const buffer_requirement&, VkMemoryPropertyFlags, buffer_info&);
|
|
memory_ptr createBuffers(const std::vector<buffer_requirement> &, VkMemoryPropertyFlags, std::vector<buffer_info> &);
|
|
|
|
void copyBuffer(buffer_info srcBuffer, buffer_info dstBuffer, VkDeviceSize size);
|
|
|
|
void setTracyZone(const char* name);
|
|
|
|
static memory_ptr GetNull();
|
|
|
|
private:
|
|
std::optional<uint32_t> findMemory(uint32_t, VkMemoryPropertyFlags, VkDeviceSize size = 0);
|
|
constexpr bool hasBudget() const { return properties2.pNext != nullptr; }
|
|
constexpr const VkPhysicalDeviceMemoryProperties &getProperties() const { return hasBudget() ? properties2.memoryProperties : properties; }
|
|
void updateProperties();
|
|
|
|
struct Allocation {
|
|
Allocation(VkDevice, VkDeviceMemory, VkDeviceSize, uint32_t, void *ptr);
|
|
~Allocation();
|
|
|
|
const VkDevice device;
|
|
const VkDeviceMemory memory;
|
|
const VkDeviceSize size;
|
|
const uint32_t memoryType;
|
|
void *const ptr = nullptr;
|
|
const MemoryDeleter deleter;
|
|
|
|
struct area { VkDeviceSize size; VkDeviceSize offset; };
|
|
std::vector<area> areas;
|
|
};
|
|
|
|
VkPhysicalDevice const physicalDevice;
|
|
VkDevice const device;
|
|
VkPhysicalDeviceMemoryProperties properties{};
|
|
VkPhysicalDeviceMemoryProperties2 properties2{};
|
|
VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{};
|
|
|
|
VkQueue transferQueue;
|
|
VkCommandPool transferPool;
|
|
VkCommandBuffer transferBuffer; // MAYBE: parallel upload
|
|
TracyVkCtx tracyCtx;
|
|
|
|
std::vector<std::unique_ptr<Allocation>> allocations;
|
|
};
|
|
} |