vkgen 0.1.9

Generates Rust source code from vk.xml
# 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> <output file>```

##### Arguments
- `input file` the Vulkan registry file to be parsed
- `output file` the file to which the generated code will be written, it will be created if it does not exist

##### Options
TBA

##### Example

```$ vkgen ./vk.xml ./vk.rs```

Parses a file called `vk.xml` which contains the Vulkan registry and writes the generated code to `vk.rs`.

### Step 3
Add libloading to your project's cargo.toml
```
[dependencies]
libloading = "0.5.0"
```
`libloading` is required to load vkGetInstanceProcAddr from the Vulkan shared library.

### Step 4
Load libvulkan in order to use the generated functions
```rust
unsafe { vkLoad("path/to/libvulkan"); }
```
Note: vkLoad() only loads vkGetInstanceProcAddr from the shared library, all other
functions are loaded dynamically via vkGetInstanceProcAddr andvkGetDeviceProcAddr
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. The location of libvulkan.so/vulkan.dll may vary depending on the OS.
```rust
mod vk;

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

fn main() {
	unsafe { vkLoad("/usr/lib/x86_64-linux-gnu/libvulkan.so.1.1.92"); }

	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:                   VkStructureType::VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
		pNext:                   null(),
		flags:                   0,
		pApplicationInfo: &VkApplicationInfo {
			sType:              VkStructureType::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),
		} as *const VkApplicationInfo,
		enabledLayerCount:       0,
		ppEnabledLayerNames:     null(),
		enabledExtensionCount:   0,
		ppEnabledExtensionNames: null()
	};

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

```