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

Download history 68946/week @ 2024-04-23 67053/week @ 2024-04-30 56723/week @ 2024-05-07 58809/week @ 2024-05-14 67177/week @ 2024-05-21 64638/week @ 2024-05-28 63147/week @ 2024-06-04 64812/week @ 2024-06-11 60317/week @ 2024-06-18 60142/week @ 2024-06-25 62754/week @ 2024-07-02 71275/week @ 2024-07-09 74362/week @ 2024-07-16 70975/week @ 2024-07-23 72792/week @ 2024-07-30 77057/week @ 2024-08-06

每月 309,788 次下载
1,728 个库中(95个直接)使用

MIT/Apache

5MB
126K SLoC

Ash

围绕Vulkan的非常轻量级的包装

Crates.io Version Documentation Build Status LICENSE LICENSE Join the chat at https://gitter.im/MaikKlein/ash MSRV

概述

  • 真正的Vulkan API,没有任何妥协
  • 便捷功能,不限制功能
  • 额外的类型安全
  • 设备本地函数指针加载
  • 无验证,一切均为 unsafe
  • 在用构建器模式创建的结构中提供生命周期安全
  • vk.xml生成
  • 支持Vulkan 1.11.21.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_rawHandle::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库。需要比 InstanceDevice 存活更长时间。
  • 实例:加载实例级别的函数。需要比它所创建的 Device 存活更长时间。
  • 设备:加载设备 本地 函数。

加载器只是可能实现之一

  • 在设备级别按设备检索函数。
  • 默认情况下加载一切,加载失败的函数初始化为总是引发恐慌的函数。
  • 如果您已创建1.0实例,请勿调用Vulkan 1.1函数。这样做将导致恐慌。

可以实施自定义加载器。

扩展加载

此外,每个Vulkan扩展都必须显式加载。您可以直接在模块的 ash::* 下找到所有扩展,它们带有前缀(例如 khrext)。

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 驱动程序,以及(可选)通过您的包管理器安装 验证层

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

screenshot

纹理

在一个四边形上显示纹理。

cargo run -p ash-examples --bin texture

texture

有用的资源

示例

实用库

  • 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