Realm

Create an instance. Find your GPUs.

Two calling styles over one Vulkan implementation. Both examples create an instance, enumerate physical devices, and explicitly destroy the instance.

RustExperimental

Prerequisites

Use Rust 1.98.1 or newer and an installed Vulkan loader and driver. These examples request Vulkan 1.0. A Vulkan SDK and C/C++ toolchain are not required.

Terminal

cargo new vk-example
cd vk-example

Add this dependency to your project:

Cargo.toml

1[dependencies]
2vk = { package = "vkrust", version = "0.12" }
3

Free functions

Pass the dispatch context explicitly. Save this example as src/main.rs:

Src/main.rs

1fn main() -> Result<(), Box<dyn std::error::Error>> {
2 // SAFETY: use the trusted system Vulkan loader; all create-info pointers
3 // remain live during creation. This example creates no child objects.
4 unsafe {
5 let entry = vk::Entry::new()?;
6 let application = vk::ApplicationInfo::new()
7 .set_application_name(c"vk example")
8 .set_api_version(vk::API_VERSION_1_0);
9 let info = vk::InstanceCreateInfo::new()
10 .set_application_info(&application);
11
12 let instance = vk::create_instance(&entry, &info, None)?;
13 let devices = vk::enumerate_physical_devices(&instance);
14 vk::destroy_instance(instance, None);
15
16 println!("Physical devices: {}", devices?.len());
17 }
18 Ok(())
19}
20

Constructors and methods

The equivalent lifecycle through vk::Instance uses the same dispatch and operations:

Src/main.rs

1fn main() -> Result<(), Box<dyn std::error::Error>> {
2 // SAFETY: use the trusted system loader; borrowed create-info storage
3 // remains live. No children or outstanding work remain at destruction.
4 unsafe {
5 let entry = vk::Entry::new()?;
6 let application = vk::ApplicationInfo::new()
7 .set_application_name(c"vk example")
8 .set_api_version(vk::API_VERSION_1_0);
9 let info = vk::InstanceCreateInfo::new()
10 .set_application_info(&application);
11
12 let instance = vk::Instance::new(&entry, &info, None)?;
13 let devices = instance.enumerate_physical_devices();
14 instance.destroy(None);
15
16 println!("Physical devices: {}", devices?.len());
17 }
18 Ok(())
19}
20

Run

Terminal

cargo run --release

A successful run prints Physical devices: N, where N is the number exposed by your Vulkan implementation. Loader and Vulkan failures propagate as errors. Enumeration cleanup runs before its result is propagated.

Borrowed record construction

Prepare native arguments with Type::new() and generated set_* setters.Type::default() produces the same initial state for default-backed records. This is the default construction approach, with no additional feature flag, and works with both free functions and methods. This example prepares records without creating GPU objects:

Borrowed records

1fn main() -> Result<(), vk::ConstructionError> {
2 let application = vk::ApplicationInfo::new()
3 .set_application_name(c"vk example")
4 .set_api_version(vk::API_VERSION_1_0);
5 let info = vk::InstanceCreateInfo::new()
6 .set_application_info(&application);
7
8 let priorities = [1.0_f32];
9 let queues = [vk::DeviceQueueCreateInfo::new()
10 .set_queue_family_index(0)
11 .set_queue_priorities(&priorities)?];
12 let device_info = vk::DeviceCreateInfo::new()
13 .set_queue_create_infos(&queues)?;
14
15 assert_eq!(info.p_application_info, &application as *const _);
16 assert_eq!(device_info.queue_create_info_count, 1);
17 Ok(())
18}
19

Setters keep backing strings, records, and arrays live through their last use. Array setters derive checked native counts. Compatible extension chains use push_next, which retains an exclusive borrow of each inserted node. Direct native fields remain available; stored borrowed records carry lifetime parameters such as Type<'a>.

Ownership and cleanup

Borrowed record setters retain host backing storage. They do not establish native resource lifetimes, enable features, or prove GPU completion. Calls remain unsafe; dropping a wrapper does not destroy its Vulkan object or wait for pending work.

If native creation succeeds but dispatch initialization cannot recover or destroy the object,CallError::InitializationFailed retains its handle and library. Applications must handle that variant to recover ownership; these introductory examples propagate it.

Examples are copied verbatim from the published VK README.