14个不稳定版本 (3个破坏性)
0.4.0 | 2024年5月3日 |
---|---|
0.3.0 | 2024年1月31日 |
0.2.2 | 2020年3月28日 |
0.2.0 | 2019年11月16日 |
0.1.3 | 2018年12月17日 |
#2 在 渲染引擎 中
每月 395 次下载
用于 4 crate
1.5MB
2K SLoC
vk-mem
本crate提供AMD Vulkan内存分配器(VMA) C/C++库的FFI层和惯用Rust封装。
问题
Vulkan中内存分配和资源(缓冲区和图像)创建因以下原因而困难(与较旧的图形API(如D3D11或OpenGL)相比):
- 它需要大量的样板代码,就像Vulkan中的所有其他东西一样,因为它是一个低级且高性能的API。
- 存在额外的间接层:VkDeviceMemory是从创建VkBuffer/VkImage独立分配的,它们必须一起绑定。绑定不能更改 - 资源必须重新创建。
- 必须查询驱动程序以支持内存堆和内存类型。不同的IHVs提供不同类型的它。
- 建议分配更大的内存块,并将它们的部分分配给特定资源。
功能
本crate可以通过提供一些高级函数来帮助游戏开发者管理内存分配和资源创建:
- 帮助根据内存的预期使用选择正确和最优内存类型的函数。
- 与Vulkan标志相比,使用高级描述表达内存所需或首选的特质。
- 分配内存块、预留并返回部分(VkDeviceMemory + 偏移 + 大小)给用户的函数。
- 库跟踪分配的内存块,以及它们内部使用和未使用的范围,为新分配找到最佳匹配的未使用范围,并尊重所有对齐和缓冲区/图像粒度的规则。
- 可以在一个调用中创建图像/缓冲区、为其分配内存并将它们绑定在一起的函数。
附加功能
- 跨平台
- Windows
- Linux
- macOS (MoltenVK)
- 经过良好测试和文档化的API
- 底层库已包含在多个商业游戏作品中。
- 详细的文档(包括VMA存储库中的完整算法描述)
- 支持自定义内存池
- 创建具有所需参数的池(例如,固定或有限的最大大小)
- 从中分配内存。
- 支持线性或伙伴分配策略
- 创建具有线性算法的池,并以一次释放、堆栈、双堆栈或环形缓冲区的方式使用它,以实现更快的分配和释放。
- 详细统计信息
- 全局、按内存堆栈和按内存类型。
- 使用的内存量
- 未使用的内存量
- 分配的块数量
- 分配次数
- 等等。
- 调试注释
- 将字符串与名称或与您自己的数据相关的不可见指针关联到每个分配。
- JSON转储
- 获得包含详细内部状态映射的JSON格式的字符串,包括分配列表及其之间的间隙。
- 将此JSON转储转换为图片以可视化内存。请参阅tools/VmaDumpVis。
- 支持内存映射
- 内部使用引用计数。
- 支持持久映射内存;只需使用适当的标志进行分配即可获得对映射指针的访问。
- 支持分配碎片化
- 调用一个函数,并让库移动数据以释放一些内存块并使您的分配更紧凑。
- 支持丢失的分配
- 使用适当的标志分配内存,并让库删除许多帧未使用的分配,为新分配腾出空间。
- 支持非一致内存和刷新分配
nonCoherentAtomSize
将自动尊重。
- 尝试检测不正确的映射内存使用
- 通过使用位模式初始化所有分配的内存来检测未初始化或已释放的内存的使用。
- 在每次分配前后验证魔法数字以检测越界内存损坏。
计划中的功能
- 广泛的单元测试和示例。
- 一些单元测试,但并非全覆盖
- 示例尚未编写 - 很可能将VMA示例移植到
ash
和vk_mem
- 记录和重放分配,以深入了解内存使用、资源转换等。
- 检查正确性,衡量性能,并收集统计信息。
示例
此crate的基本用法非常简单;高级功能是可选的。
在您创建一个vk_mem::Allocator
实例后,创建缓冲区所需的代码很少
// Create the buffer (GPU only, 16KiB in this example)
let create_info = vk_mem::AllocationCreateInfo {
usage: vk_mem::MemoryUsage::GpuOnly,
..Default::default()
};
let (buffer, allocation, allocation_info) = allocator
.create_buffer(
&ash::vk::BufferCreateInfo::builder()
.size(16 * 1024)
.usage(ash::vk::BufferUsageFlags::VERTEX_BUFFER | ash::vk::BufferUsageFlags::TRANSFER_DST)
.build(),
&create_info,
)
.unwrap();
// Do stuff with buffer! (type is ash::vk::Buffer)
// Destroy the buffer
allocator.destroy_buffer(buffer, &allocation).unwrap();
通过此一个函数调用(vk_mem::Allocator::create_buffer
)
ash::vk::Buffer
(VkBuffer
)被创建。ash::vk::DeviceMemory
(VkDeviceMemory
)块在需要时分配。- 内存块未使用的区域绑定到该缓冲区。
vk_mem::Allocation
被创建,代表分配给该缓冲区的内存。它可以查询有关Vulkan内存句柄和偏移量的参数。
MoltenVK
对于macOS上的MoltenVK,您需要设置正确的环境变量。例如
export SDK_PATH=/path/to/vulkansdk-macos-1.1.106.0
export DYLD_LIBRARY_PATH=$SDK_PATH/macOS/lib
export VK_ICD_FILENAMES=$SDK_PATH/macOS/etc/vulkan/icd.d/MoltenVK_icd.json
export VK_LAYER_PATH=$SDK_PATH/macOS/etc/vulkan/explicit_layer.d
cargo test
用法
将其添加到您的Cargo.toml
[dependencies]
vk-mem = "0.3.0"
并将其添加到您的crate根目录
extern crate vk_mem;
使用MinGW W64编译
Vulkan 内存分配器需要 C++11 线程。MinGW W64 默认不支持这些线程,因此您需要切换到 POSIX 构建方式。例如,在 Debian 上,您需要运行以下命令
update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix
update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix
许可协议
根据以下任一许可协议进行许可
- Apache 许可协议,版本 2.0 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可协议 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
致谢与特别感谢
- Adam Sawicki - AMD(C/C++ 库的作者)
- Maik Klein(ash - Vulkan Rust 绑定的作者)
- Johan Andersson(贡献)
- Patrick Minogue(贡献)
- Layl Conway(贡献)
- aloucks(贡献)
- Henrik Rydgård(贡献)
- msiglreith(贡献)
- Maksym Pavlenko(贡献)
- Brandon Pollack(贡献)
贡献
除非您明确表示,否则根据 Apache-2.0 许可协议定义的,任何有意提交以包含在此包中的贡献,都将如上所述双重许可,不附加任何额外条款或条件。
我们始终欢迎贡献;请查看问题追踪器以了解已记录的已知改进。
行为准则
对 vk-mem 包的贡献是在贡献者公约的条款下组织的,vk-mem 的维护者 @Neo-Zhixing 承诺将介入以维护该行为准则。
依赖项
~5–10MB
~134K SLoC