nobs-vk

no bullshit vulkan bindings.

This crate is auto generated by python scripts and provides types, constants and functions for vulkan.

  1. Existential questions
  2. Examples
    1. Vulkan core initialisation
    2. Instance extension loading
  3. Details
    1. Namespaces
    2. Function pointers
    3. Traits for rich instance and device wrapper

Existential questions

Why does nobs-vk exists? nobs-vk... 1. is used how the vulkan api is documented 2. is auto generated from a python script that sources the vk.xml from the vulkan registry 3. gives you the freedom to do as you please in your design decisions (but therefore doesn't protect you from your own stupidity) 4. is not a full blown window creating bloat library in the back, just to execute some small compute shader with a headless vulkan build

While more involved wrappers for vulkan do exist they also strife to completely hide the vulkan api behind another layer of rust code. nobs-vk tries to be as simple as possible and just exposes callable functions to vulkan.

Examples

Vulkan core initialisation

This is a simple example that retrieves the version of vulkan that is installed on the system ```rust

[macrouse] extern crate nobsvk as vk;

//...

fn main() {

// loads vulkan core let vklib = vk::Core::new();

// good to go from here, we can use any vulkan function that is supported by this system // make sure vklib lives throughout the time that vulkan is used and is dropped afterwards

// global vulkan version let mut instver: u32 = 0; if vk::EnumerateInstanceVersion(&mut instver) != vk::SUCCESS { panic!("something went terribly wrong"); }

asserteq!(1, versionmajor!(instver)); asserteq!(1, versionminor!(instver)); asserteq!(0, versionpatch!(inst_ver));

}

```

Instance extension loading

After we created a vulkan instance we can load extensions ```rust

[macrouse] extern crate nobsvk as vk;

use std::ffi::CString; use std::ffi::CStr; use std::ptr; use std::os::raw::c_char;

fn main() {

// ... let vklib = vk::Core::new();

// Define some extensions and convert them to c-strings let extnames = vec![vk::KHRSURFACEEXTENSIONNAME, vk::KHRXLIBSURFACEEXTENSIONNAME]; let extnamescstr = extnames .iter() .map(|e| CString::new(*e).unwrap()) .collect::>(); let extnamesptr = extnamescstr .iter() .map(|e| e.asptr()) .collect::>();

// create the instance let appinfo = vk::InstanceCreateInfo { sType: vk::STRUCTURETYPEINSTANCECREATEINFO, pNext: ptr::null(), flags: 0, pApplicationInfo: ptr::null(), enabledLayerCount: 0, ppEnabledLayerNames: ptr::null(), enabledExtensionCount: extnames.len() as u32, // <- extension names go here ppEnabledExtensionNames: extnamesptr.asptr(), // <- };

let mut inst = vk::NULL_HANDLE; vk::CreateInstance(&appinfo, ptr::null(), &mut inst);

// not an extension, so we can call it no matter what let mut numdevices: u32 = 0; vk::EnumeratePhysicalDevices(inst, &mut numdevices, ptr::nullmut()); println!("num devices: {}", numdevices);

// load extensions // note that only extensions are loaded, that have been specified in ext_names let ie = vk::InstanceExtensions::new(inst); // we can now use instence extensions, e.g.: // ie.CreateXlibSurfaceKHR(...)

// don't forget to clean up vk::DestroyInstance(inst, ptr::null());

}

```

Details

Vulkan commands are either core or extension. We provide two different mechanisms to load function pointers.

Core commands are loaded with nobsvk::Core::new or nobsvk::Core::with_version. The returned object holds entry points to core vulkan commands and defines member function to call them. Additionaly global functions in the nobs_vk namespace are defined that may be called as long as a valid instance of nobs_vk::Core exists. Warning: do not create multiple instances of nobs_vk::Core.

Instance and device extensions are loaded with nobs_vk::[InstanceExtensions|DeviceExtensions]. The two types hold entry points to vulkan extensions and define member functions to call them. Only those extension are loaded, that have been specified during instance/device creation (enabledExtensionCount and ppEnabledExtensionNames fields of fields of VkInstanceCreateInfo and VkDeviceCreateInfo).

Namespaces

Name prefixes of the C-types, enums and (core) functions are removed in favor of the module namespace. For example VK_Result becomes vk::Result, VK_SUCCESS becomes vk::SUCCESS, vkCreateInstance() becomes vk::CreateInstance().

Function pointers

nobs-vk defines functions for all extensions that have been specified in the generate.py. This all its required types, function pointers and methods in nobs_vk::[InstanceExtensions|DeviceExtensions] are generated. In case a system does not support an extension the function pointer will not be loaded, and calling its respectiove method causes a panic.

Traits for rich instance and device wrapper

nobs-vk provides the traits InstanceWreapper and InstanceWreapper. Both are intended to be used in a implementation a rich wrapper around a vulkan instance or device. They extend an object that can provide a InstanceExtension or DeviceExtension with methods to call vulkan commands directly on the object. The provided methods are simple pass through to the actual function pointer.

Vulkan reference

For documentation of the defined enums, structs and funcions see the vulkan reference.