Files
mirai/src/render/allocator.h

126 lines
3.1 KiB
C++

#pragma once
#include "types/types.h"
#include "resource_types.h"
#include "core/object.h"
#include <vulkan/vulkan.hpp>
#include <vma/vk_mem_alloc.h>
namespace mirai {
struct allocation_info {
// 分配的大小(字节)
u64 size = 0;
// 偏移量(字节)
u64 offset = 0;
// 设备内存句柄
vk::DeviceMemory device_memory{};
// 映射的内存指针
void* mapped_ptr = nullptr;
// 内存类型索引
u32 memory_type_index = 0;
// 分配标志
vk::MemoryPropertyFlags property_flags{};
};
struct buffer_allocation_info {
/// Buffer 大小(字节)
u64 size = 0;
/// Buffer 用途
buffer_usage usage = buffer_usage::vertex;
/// 内存用途
memory_usage mem_usage = memory_usage::gpu_only;
/// 是否需要持久映射
bool persistent_mapped = false;
/// 调试名称
std::string_view debug_name;
};
/**
* @brief Buffer 分配结果
*/
struct buffer_allocation {
/// Vulkan Buffer 句柄
vk::Buffer buffer{};
/// VMA 分配句柄
VmaAllocation allocation = VK_NULL_HANDLE;
/// 分配信息
allocation_info info;
/// 是否有效
[[nodiscard]] bool is_valid() const noexcept {
return buffer && allocation != VK_NULL_HANDLE;
}
};
/**
* @brief Image 分配创建信息
*/
struct image_allocation_info {
/// 图像类型
vk::ImageType image_type = vk::ImageType::e2D;
/// 图像格式
vk::Format format = vk::Format::eR8G8B8A8Unorm;
/// 图像范围
vk::Extent3D extent = {1, 1, 1};
/// Mip 层级数
u32 mip_levels = 1;
/// 数组层数
u32 array_layers = 1;
/// 采样数
vk::SampleCountFlagBits samples = vk::SampleCountFlagBits::e1;
/// 平铺方式
vk::ImageTiling tiling = vk::ImageTiling::eOptimal;
/// 图像用途
vk::ImageUsageFlags usage = vk::ImageUsageFlagBits::eSampled;
/// 初始布局
vk::ImageLayout initial_layout = vk::ImageLayout::eUndefined;
/// 内存用途
memory_usage mem_usage = memory_usage::gpu_only;
/// 是否为立方体贴图
bool is_cube = false;
/// 调试名称
std::string_view debug_name;
};
/**
* @brief Image 分配结果
*/
struct image_allocation {
/// Vulkan Image 句柄
vk::Image image{};
/// VMA 分配句柄
VmaAllocation allocation = VK_NULL_HANDLE;
/// 分配信息
allocation_info info;
/// 是否有效
[[nodiscard]] bool is_valid() const noexcept {
return image && allocation != VK_NULL_HANDLE;
}
};
/**
* @brief GPU 分配器配置
*/
struct allocator_config {
/// Vulkan 实例
vk::Instance instance{};
/// 物理设备
vk::PhysicalDevice physical_device{};
/// 逻辑设备
vk::Device device{};
/// Vulkan API 版本
u32 vulkan_api_version = VK_API_VERSION_1_3;
/// 是否启用 Buffer Device Address
bool enable_buffer_device_address = true;
/// 是否启用内存预算跟踪
bool enable_memory_budget = true;
/// 首选的大块分配大小(字节)
u64 preferred_large_heap_block_size = 256 * 1024 * 1024; // 256 MB
};
class vma_allocator : public object {
MIRAI_OBJECT_TYPE_INFO(vma_allocator, object)
explicit vma_allocator(const allocator_config& config);
~vma_allocator() override;
};
}