6个版本
使用旧Rust 2015
| 0.1.6 | 2016年7月11日 |
|---|---|
| 0.1.5 | 2016年7月8日 |
| 0.1.2 | 2016年6月30日 |
在图形API中排名第697
265KB
4.5K SLoC
Dvk是一个提供Vulkan API绑定的库。与其他许多替代方案不同,Dvk在运行时动态加载所有Vulkan命令,使编译变得更加简单,以至于即使不需要安装Vulkan也可以编译。
该库的设计遵循最小惊讶原则,它与官方头文件几乎不偏离,不会无谓地污染官方Vulkan命名空间。只有少数地方由于语言差异或需要动态加载而迫使设计偏离标准,所有这些特殊性都在本页上进行了详细说明。标准的Khronos文档应该足以了解该库提供所有类型和函数。
注意:在当前版本中,只有khr_win32_surface完成了所有平台特定WSI扩展。
文档
https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html
组织
所有定义都组织到模块中,主要的是core,其余的khr_surface、ext_debug_report、khr_display、khr_display_swapchain、khr_swapchain、khr_win32_surface都是扩展。该库不导出任何可用的命令原型。所有定义的顺序与vulkan.h头文件中的顺序相同。
官方API的更改
类型
VkClearValueUnionVkClearColorValueUnionVkCoreCommandsVkKhrSurfaceCommandsVkKhrSwapchainCommandsVkKhrDisplayCommandsVkKhrDisplaySwapchainCommandsVkKhrWin32SurfaceCommandsVkExtDebugReportCommands- 没有单独的
*FlagBits和*Flags类型,只有*Flags VkDescriptorPoolSize.type更名为dType,因为与Rust关键字type命名冲突。- 平台类型作为库的一部分重新定义
- 没有通用的VK_NULL_HANDLE常量,它与类型安全句柄不兼容
函数
Vulkan*::new()和Vulkan*::load(&mut self, VkInstance)::null()构造函数和所有句柄的::is_null(&self)方法- 从
*Union类型的特质实现
加载
动态加载相对于静态链接的优势在于无需静态库即可编译。Vulkan 标准在这方面相当保守,只保证从动态库中导出单个命令。该命令是 vkGetInstanceProcAddr。一旦获取了该命令,就可以使用它来加载下一级 API,该 API 由三个 全局命令 组成
vkCreateInstancevkEnumerateInstanceExtensionPropertiesvkEnumerateInstanceLayerProperties
API 的其余部分,由 134 个核心命令 组成,可以类似地通过 vkGetInstanceProcAddr 加载,但需要 VkInstance 对象来加载它们。不出所料,可以通过全局命令 vkCreateInstance 创建 VkInstance 对象。扩展命令以完全相同的方式加载。
该库不导出任何现成的命令原型,而是以结构体返回所有动态加载的命令。
Vulkan 功能的核心位于 VkCoreCommands 结构体中。它提供了所有核心 Vulkan 命令作为方法。当通过调用 VkCoreCommands::new() 初始创建 VkCoreCommands 时,它将已经加载了 3 个全局命令 并准备好使用。如果在此时尝试调用任何未加载的命令,将导致 panic。下一步应该是创建一个 VkInstance 对象并调用 VkCoreCommands::load(&mut self, VkInstance instance) 方法,并将其作为参数传递。Vulkan 准备就绪。
扩展通过 VkKhrSurfaceCommands、VkKhrSwapchainCommands、VkKhrDisplayCommands、VkKhrDisplaySwapchainCommands、VkKhrWin32SurfaceCommands 等类似方式加载。
该库不支持使用 vkGetDeviceProcAddr 加载设备优化的命令指针。这种省略的原因是,以这种方式加载函数引入了大量的意外复杂性,并使库难以使用。
平台类型
平台类型被重新定义以避免操作系统特定的依赖,使用 std::mem::transmute 在它们之间进行转换。当前的平台类型有
dvk::khr_win32_surface::platform::HINSTANCEdvk::khr_win32_surface::platform::HWND
联合
由于Rust没有与C联合体相对应的结构,因此它们通过标签联合类型和From trait的组合来模拟。每当Vulkan需要名为VkSomeTypeName的联合体时,构造一个类型为VkSomeTypeNameUnion的值,并调用其上的into(self)方法来获取VkSomeTypeName。例如
let foo: VkClearColorValue = VkClearColorValueUnion::Float32([1,2,3]).into();
句柄
所有句柄都是类型安全的,这不幸地使得生成“NULL”句柄变得很尴尬。因此,所有句柄类型都实现了null函数来构建空句柄,以及相应的is_null方法来检查句柄是否为空。
用法
以下是一个简短的示例,用于说明基本用法
#[macro_use]
extern crate dvk;
use dvk::core::*;
use dvk::khr_surface::*;
use dvk::khr_win32_surface::*;
...
// This will load vulkan shared library and 3 global commands
let mut core = VkCoreCommands::new().unwrap();
// The null method is used to get type-safe "NULL" handles
let mut instance = VkInstance::null();
// vkCreateInstance is one of the 3 global commands
// that can be loaded without an instance object
core.vkCreateInstance(&instance_create_info, null(), &mut context.instance);
// Calling unloaded command will cause a panic
core.vkEnumeratePhysicalDevices(...); // ERROR!
// After you've acquired an instance object the remaining commands can be loaded
core.load(instance).unwrap();
// The rest of commands are loaded and ready to use now
core.vkEnumeratePhysicalDevices(...);
core.vkCreateDevice(...);
core.vkQueueSubmit(...);
// Using intermediate VkClearValueUnion Rust-style enum to
// construct VkClearValue corresponding to C-style union
let clear_depth_stencil_value = VkClearDepthStencilValue{depth:0.0f32, stencil: 0u32};
let clear_value: VkClearValue = VkClearValueUnion::DepthStencil(clear_depth_stencil_value).into();
示例代码
更完整的示例可以在examples/triangle.rs中找到。要编译(或运行)它,请
> cargo build(or run) --examples triangle
依赖项
~215KB