use std::ffi::CStr;
use vulkane::raw::bindings::*;
use vulkane::raw::{VkResultExt, VulkanLibrary};
#[test]
fn test_real_vulkan_loader() {
let library = match VulkanLibrary::new() {
Ok(lib) => lib,
Err(e) => {
eprintln!("SKIP: Vulkan library not available on this system: {}", e);
return;
}
};
println!("[OK] Loaded Vulkan shared library");
let entry = unsafe { library.load_entry() };
println!("[OK] Loaded entry dispatch table");
let enumerate_version = entry
.vkEnumerateInstanceVersion
.expect("vkEnumerateInstanceVersion should be available");
let mut api_version: u32 = 0;
unsafe { enumerate_version(&mut api_version) }
.into_result()
.expect("vkEnumerateInstanceVersion should succeed");
let major = vk_api_version_major(api_version);
let minor = vk_api_version_minor(api_version);
let patch = vk_api_version_patch(api_version);
println!("[OK] Driver supports Vulkan {}.{}.{}", major, minor, patch);
assert!(major >= 1, "Vulkan major version should be at least 1");
let create_instance = entry
.vkCreateInstance
.expect("vkCreateInstance should be available");
let app_name = c"vulkane-real-vulkan-test";
let engine_name = c"vulkane";
let app_info = VkApplicationInfo {
sType: VkStructureType::STRUCTURE_TYPE_APPLICATION_INFO,
pNext: std::ptr::null(),
pApplicationName: app_name.as_ptr(),
applicationVersion: vk_make_api_version(0, 0, 1, 0),
pEngineName: engine_name.as_ptr(),
engineVersion: vk_make_api_version(0, 0, 1, 0),
apiVersion: VK_API_VERSION_1_0,
};
let create_info = VkInstanceCreateInfo {
sType: VkStructureType::STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
pNext: std::ptr::null(),
flags: 0,
pApplicationInfo: &app_info,
enabledLayerCount: 0,
ppEnabledLayerNames: std::ptr::null(),
enabledExtensionCount: 0,
ppEnabledExtensionNames: std::ptr::null(),
};
let mut instance: VkInstance = std::ptr::null_mut();
let result = unsafe { create_instance(&create_info, std::ptr::null(), &mut instance) };
if result == VkResult::ERROR_INCOMPATIBLE_DRIVER {
eprintln!("SKIP: Vulkan loader is present but no compatible driver is installed");
return;
}
assert_eq!(
result,
VkResult::SUCCESS,
"vkCreateInstance should return SUCCESS, got {:?}",
result
);
assert!(!instance.is_null(), "VkInstance should not be null");
println!("[OK] Created VkInstance: {:p}", instance);
let instance_table = unsafe { library.load_instance(instance) };
println!("[OK] Loaded instance dispatch table");
let enumerate_devices = instance_table
.vkEnumeratePhysicalDevices
.expect("vkEnumeratePhysicalDevices should be available");
let mut device_count: u32 = 0;
let result = unsafe { enumerate_devices(instance, &mut device_count, std::ptr::null_mut()) };
assert_eq!(
result,
VkResult::SUCCESS,
"vkEnumeratePhysicalDevices count query should succeed, got {:?}",
result
);
println!("[OK] Found {} physical device(s)", device_count);
if device_count == 0 {
println!("NOTE: No physical devices available; skipping device-level checks");
} else {
let mut devices: Vec<VkPhysicalDevice> = vec![std::ptr::null_mut(); device_count as usize];
let result =
unsafe { enumerate_devices(instance, &mut device_count, devices.as_mut_ptr()) };
assert_eq!(
result,
VkResult::SUCCESS,
"vkEnumeratePhysicalDevices fetch should succeed, got {:?}",
result
);
let get_props = instance_table
.vkGetPhysicalDeviceProperties
.expect("vkGetPhysicalDeviceProperties should be available");
for (i, &device) in devices.iter().enumerate() {
assert!(
!device.is_null(),
"Physical device {} should not be null",
i
);
let mut props: VkPhysicalDeviceProperties = unsafe { std::mem::zeroed() };
unsafe { get_props(device, &mut props) };
let device_name = unsafe {
CStr::from_ptr(props.deviceName.as_ptr())
.to_string_lossy()
.into_owned()
};
let dev_major = vk_api_version_major(props.apiVersion);
let dev_minor = vk_api_version_minor(props.apiVersion);
let dev_patch = vk_api_version_patch(props.apiVersion);
println!(
"[OK] Device {}: \"{}\" (Vulkan {}.{}.{}, type={:?})",
i, device_name, dev_major, dev_minor, dev_patch, props.deviceType
);
assert!(!device_name.is_empty(), "Device name should not be empty");
assert!(dev_major >= 1, "Device API version major should be >= 1");
}
}
let destroy_instance = instance_table
.vkDestroyInstance
.expect("vkDestroyInstance should be available");
unsafe { destroy_instance(instance, std::ptr::null()) };
println!("[OK] Destroyed VkInstance");
println!("\n=== Real Vulkan loader test PASSED ===");
}