#vulkan #vk #generator

app vkgen

Generates Rust source code from the Vulkan registry

12 releases (2 stable)

✓ Uses Rust 2018 edition

1.1.0 May 11, 2019
1.0.0 Mar 25, 2019
0.1.9 Feb 9, 2019
0.1.8 Jan 30, 2019

#33 in Graphics APIs

Download history 12/week @ 2019-01-23 23/week @ 2019-01-30 13/week @ 2019-02-06 3/week @ 2019-02-13 5/week @ 2019-02-20 27/week @ 2019-02-27 3/week @ 2019-03-06 2/week @ 2019-03-13 120/week @ 2019-03-20 17/week @ 2019-03-27 17/week @ 2019-04-03 4/week @ 2019-04-10 13/week @ 2019-04-24 12/week @ 2019-05-01

75 downloads per month

MIT license

57KB
1K SLoC

vkgen

Generates Rust source code from vk.xml

Benefits

  • easy to use
  • no dependencies except libloading
  • only ~1.000 lines of code which ensures easy maintainability
  • can easily be modified to support other languages (just replace gen() with your own code)

General information

  • libloading is required to load vkGetInstanceProcAddr from the Vulkan shared library
  • all other functions are loaded dynamically during runtime via vkGetInstanceProcAddr and vkGetDeviceProcAddr
  • a very thin wrapper is generated for all dispatchable handles to store function pointers / parent handles, but without any remarkable performance penalties

Usage

Step 1

Download vk.xml from the official Vulkan-Headers repository (https://github.com/KhronosGroup/Vulkan-Headers/blob/master/registry/vk.xml)

Step 2

Generate Rust source code from vk.xml

$ vkgen <input file>

Arguments
  • input file is the Vulkan registry file to be parsed
Output
  • <input file>.rs contains the generated source code
  • <input file>.toml contains a list of all versions and extensions
Example

$ vkgen ./vk.xml

Parses a file named vk.xml which contains the Vulkan registry and outputs the generated code to vk.rs and a list of all versions and extensions to vk.toml.

Step 3

Copy the Rust file into your project folder and add the versions and extensions located in the toml file to your project's Cargo.toml:

...
[features]
default = ["VK_VERSION_1_0", "VK_VERSION_1_1"]
...
VK_VERSION_1_0 = []
VK_VERSION_1_1 = []
...

Step 4

Add libloading to your project's cargo.toml

[dependencies]
libloading = "0.5.0"

libloading is used to load vkGetInstanceProcAddr from the Vulkan shared library.

Step 5

Load libvulkan in order to use the generated functions

unsafe { vkLoad(); }

Note: vkLoad() only loads vkGetInstanceProcAddr from the shared library, all other functions are loaded dynamically via vkGetInstanceProcAddr and vkGetDeviceProcAddr to avoid additional dispatch overhead.

Examples

This simple example demonstrates how to load libvulkan on linux, output the instance version (1.1.0) and create an instance. vk.rs is the file containing the generated Rust source code.

Cargo.toml:

[package]
name = "vkgen_test"
version = "0.1.0"
authors = ["tobias"]
edition = "2018"

[features]
default = ["VK_VERSION_1_0", "VK_VERSION_1_1"]
VK_VERSION_1_0 = []
VK_VERSION_1_1 = []

[dependencies]
libloading = "0.5.0"

main.rs:

mod vk;

use self::vk::*;
use std::ptr::null;

fn main() {
	unsafe { vkLoad(); }

	let mut v: u32 = 0;
	enumerateInstanceVersion(&mut v);
	println!("vulkan instance version is {}.{}.{}", VK_VERSION_MAJOR(v), VK_VERSION_MINOR(v), VK_VERSION_PATCH(v));

	let instance_info = VkInstanceCreateInfo {
		sType:                   VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
		pNext:                   null(),
		flags:                   0,
		pApplicationInfo: &VkApplicationInfo {
			sType:              VK_STRUCTURE_TYPE_APPLICATION_INFO,
			pNext:              null(),
			pApplicationName:   b"test app\0".as_ptr(),
			applicationVersion: VK_MAKE_VERSION(0, 0, 1),
			pEngineName:        b"test engine\0".as_ptr(),
			engineVersion:      VK_MAKE_VERSION(0, 0, 1),
			apiVersion:         VK_MAKE_VERSION(1, 1, 0),
		},
		enabledLayerCount:       0,
		ppEnabledLayerNames:     null(),
		enabledExtensionCount:   0,
		ppEnabledExtensionNames: null()
	};

	let mut instance = VK_NULL_HANDLE;
	if createInstance(&instance_info, null(), &mut instance) != VK_SUCCESS {
		panic!("something went wrong :-/");
	};
	let instance = unsafe { VkInstanceImpl::new(instance) };
}

No runtime deps