71个版本
0.38.0+1.3.281 | 2024年4月1日 |
---|---|
0.37.3+1.3.251 | 2023年5月29日 |
0.37.2+1.3.238 | 2023年1月11日 |
0.37.1+1.3.235 | 2022年11月23日 |
0.9.0 | 2016年12月29日 |
#1 in 图形API
每月 309,788 次下载
在1,728 个库中(95个直接)使用
5MB
126K SLoC
Ash
围绕Vulkan的非常轻量级的包装
概述
- 真正的Vulkan API,没有任何妥协
- 便捷功能,不限制功能
- 额外的类型安全
- 设备本地函数指针加载
- 无验证,一切均为 unsafe
- 在用构建器模式创建的结构中提供生命周期安全
- 由
vk.xml
生成 - 支持Vulkan
1.1
,1.2
,1.3
-
no_std
支持
⚠️ Semver兼容性警告
由于Vulkan视频绑定处于实验性阶段,其上游规范仍在进行破坏性变更,因此Ash只为早期采用者提供。所有相关函数和类型均免于Semver限制 [^1](我们允许在Ash的非破坏性Semver升级期间进行破坏性API更改)。
[^1]: generator
的复杂性使得我们无法轻易将这些绑定隐藏在非default
功能标志后面,并且它们在生成的代码库中很普遍。
特性
使用Result
显式返回
// function signature
pub fn create_instance(&self,
create_info: &vk::InstanceCreateInfo<'_>,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>)
-> Result<Instance, InstanceError> { .. }
let instance = entry.create_instance(&create_info, None)
.expect("Instance creation error");
Vec<T>
代替可变切片
pub fn get_swapchain_images(&self,
swapchain: vk::SwapchainKHR)
-> VkResult<Vec<vk::Image>>;
let present_images = swapchain_loader.get_swapchain_images_khr(swapchain).unwrap();
注意:如果这会限制功能,则函数不会返回Vec<T>
。请参阅p_next
。
切片
pub fn cmd_pipeline_barrier(&self,
command_buffer: vk::CommandBuffer,
src_stage_mask: vk::PipelineStageFlags,
dst_stage_mask: vk::PipelineStageFlags,
dependency_flags: vk::DependencyFlags,
memory_barriers: &[vk::MemoryBarrier<'_>],
buffer_memory_barriers: &[vk::BufferMemoryBarrier<'_>],
image_memory_barriers: &[vk::ImageMemoryBarrier<'_>]);
强类型句柄
每个Vulkan句柄类型都作为具有改进类型安全的新类型结构体公开。可以使用 T::null()
构造空句柄,并且句柄可以自由地转换为 u64
并从 Handle::from_raw
和 Handle::as_raw
转换回来,以与非Ash Vulkan代码进行互操作。
构建者模式
let queue_info = [vk::DeviceQueueCreateInfo::default()
.queue_family_index(queue_family_index)
.queue_priorities(&priorities)];
let device_create_info = vk::DeviceCreateInfo::default()
.queue_create_infos(&queue_info)
.enabled_extension_names(&device_extension_names_raw)
.enabled_features(&features);
let device: Device = instance
.create_device(pdevice, &device_create_info, None)
.unwrap();
指针链
使用 base.push_next(ext)
在 base
所附加的指针链前插入 ext
。
let mut variable_pointers = vk::PhysicalDeviceVariablePointerFeatures::default();
let mut corner = vk::PhysicalDeviceCornerSampledImageFeaturesNV::default();
let mut device_create_info = vk::DeviceCreateInfo::default()
.push_next(&mut corner)
.push_next(&mut variable_pointers);
.push_next()
的泛型参数只允许有效的结构体扩展给定的结构体(在Vulkan注册表中称为 structextends
,映射到 Extends*
特性)。只有列在任何 structextends
中的结构体才会实现 .push_next()
。
标志和常量作为关联常量
// Bitflag
vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE
// Constant
vk::PipelineBindPoint::GRAPHICS,
标志的调试/显示
let flag = vk::AccessFlags::COLOR_ATTACHMENT_READ
| vk::AccessFlags::COLOR_ATTACHMENT_WRITE;
println!("Debug: {:?}", flag);
println!("Display: {}", flag);
// Prints:
// Debug: AccessFlags(110000000)
// Display: COLOR_ATTACHMENT_READ | COLOR_ATTACHMENT_WRITE
函数指针加载
Ash也负责加载函数指针。函数指针分为3类。
- 入口:加载Vulkan库。需要比
Instance
和Device
存活更长时间。 - 实例:加载实例级别的函数。需要比它所创建的
Device
存活更长时间。 - 设备:加载设备 本地 函数。
加载器只是可能实现之一
- 在设备级别按设备检索函数。
- 默认情况下加载一切,加载失败的函数初始化为总是引发恐慌的函数。
- 如果您已创建1.0实例,请勿调用Vulkan 1.1函数。这样做将导致恐慌。
可以实施自定义加载器。
扩展加载
此外,每个Vulkan扩展都必须显式加载。您可以直接在模块的 ash::*
下找到所有扩展,它们带有前缀(例如 khr
或 ext
)。
use ash::khr;
let swapchain_loader = khr::swapchain::Device::new(&instance, &device);
let swapchain = swapchain_loader.create_swapchain(&swapchain_create_info).unwrap();
原始函数指针
如果高级API中尚未公开某些内容,则可提供原始函数指针。如果有任何缺失,请提交一个问题。
device.fp_v1_0().destroy_device(...);
对扩展名称的支持
use ash::{ext, khr};
#[cfg(all(unix, not(target_os = "android")))]
fn extension_names() -> Vec<*const i8> {
vec![
khr::surface::NAME.as_ptr(),
khr::xlib_surface::NAME.as_ptr(),
ext::debug_utils::NAME.as_ptr(),
]
}
隐式句柄
从实例或设备传递句柄是隐式的。
pub fn create_command_pool(&self,
create_info: &vk::CommandPoolCreateInfo<'_>)
-> VkResult<vk::CommandPool>;
let pool = device.create_command_pool(&pool_create_info).unwrap();
可选链接
默认的 loaded
cargo功能将使用 Entry::load
动态加载当前平台的默认Vulkan库,这意味着构建环境不需要安装Vulkan开发包。
另一方面,如果您的应用程序无法处理在运行时缺少Vulkan,您可以选择启用 linked
功能,这将直接将您的二进制文件与Vulkan加载器链接,并公开坚不可摧的 Entry::linked
。
在 no_std
环境中使用
可以通过禁用 std
功能在 no_std
环境中使用Ash(带有 alloc
)。
示例
您可以在以下位置找到示例:这里。所有示例目前都需要:LunarG 验证层和一个在您的 PATH
中可见的 Vulkan 库。开始的一个简单方法是使用 LunarG Vulkan SDK
Windows
请确保您有可用的 Vulkan 驱动程序,并安装 LunarG Vulkan SDK。
Linux
安装您选择的图形硬件的 Vulkan 驱动程序,以及(可选)通过您的包管理器安装 验证层
- Arch Linux: https://wiki.archlinux.org/title/Vulkan.
- Gentoo: https://wiki.gentoo.org/wiki/Vulkan.
- Ubuntu/Debian: 除了安装兼容的图形驱动程序外,还要安装
vulkan-validationlayers
(《Debian》Debian)以使用验证层。 - 其他发行版:请咨询您的发行版文档和/或软件包仓库以了解安装和使用 Vulkan 的首选方法。
macOS
安装 LunarG Vulkan SDK。安装程序默认将 SDK 放在 $HOME/VulkanSDK/<版本>
。在运行 cargo 时,您需要设置以下环境变量
VULKAN_SDK=$HOME/VulkanSDK/<version>/macOS \
DYLD_FALLBACK_LIBRARY_PATH=$VULKAN_SDK/lib \
VK_ICD_FILENAMES=$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json \
VK_LAYER_PATH=$VULKAN_SDK/share/vulkan/explicit_layer.d \
cargo run ...
三角形
显示带有顶点颜色的三角形。
cargo run -p ash-examples --bin triangle
纹理
在一个四边形上显示纹理。
cargo run -p ash-examples --bin texture
有用的资源
示例
- vulkan-tutorial-rust - vulkan-tutorial.com 的移植。
- ash-sample-progression - LunarG 示例的移植。
- ash-nv-rt 为 ash 的一个光线追踪示例。
实用库
- vk-sync - 使用 rust 编写的简化 Vulkan 同步逻辑。
- vk-mem-rs - 此 crate 提供了 FFI 层和用于出色的 AMD Vulkan 内存分配器 C/C++ 库的惯用 Rust 包装器。
- gpu-allocator - 使用纯 Rust 编写的针对 Vulkan 和 DirectX 12 的 GPU 内存分配器。
- lahar - 用于异步上传数据到 Vulkan 设备的工具。
使用 ash 的库
- gfx-rs - gfx-rs 是一个低级别、跨平台的图形抽象库,用 Rust 实现。
致谢
依赖关系
~0–5.5MB