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的更改
类型
VkClearValueUnion
VkClearColorValueUnion
VkCoreCommands
VkKhrSurfaceCommands
VkKhrSwapchainCommands
VkKhrDisplayCommands
VkKhrDisplaySwapchainCommands
VkKhrWin32SurfaceCommands
VkExtDebugReportCommands
- 没有单独的
*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 由三个 全局命令 组成
vkCreateInstance
vkEnumerateInstanceExtensionProperties
vkEnumerateInstanceLayerProperties
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::HINSTANCE
dvk::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