kronos_compute/implementation/
instance.rs1use crate::sys::*;
4use crate::core::*;
5use crate::ffi::*;
6use std::ptr;
7use std::sync::atomic::{AtomicU64, Ordering};
8use std::sync::Mutex;
9use std::collections::HashMap;
10
11static INSTANCE_COUNTER: AtomicU64 = AtomicU64::new(1);
13
14lazy_static::lazy_static! {
16 static ref INSTANCES: Mutex<HashMap<u64, InstanceData>> = Mutex::new(HashMap::new());
17}
18
19struct InstanceData {
20 app_info: ApplicationInfo,
21 enabled_extensions: Vec<String>,
22}
23
24struct ApplicationInfo {
25 app_name: String,
26 app_version: u32,
27 engine_name: String,
28 engine_version: u32,
29 api_version: u32,
30}
31
32#[no_mangle]
34pub unsafe extern "C" fn vkCreateInstance(
35 pCreateInfo: *const VkInstanceCreateInfo,
36 _pAllocator: *const VkAllocationCallbacks,
37 pInstance: *mut VkInstance,
38) -> VkResult {
39 if pCreateInfo.is_null() || pInstance.is_null() {
40 return VkResult::ErrorInitializationFailed;
41 }
42
43 let create_info = &*pCreateInfo;
44
45 let app_info = if !create_info.pApplicationInfo.is_null() {
47 let info = &*create_info.pApplicationInfo;
48 ApplicationInfo {
49 app_name: c_str_to_string(info.pApplicationName).unwrap_or_default(),
50 app_version: info.applicationVersion,
51 engine_name: c_str_to_string(info.pEngineName).unwrap_or_default(),
52 engine_version: info.engineVersion,
53 api_version: info.apiVersion,
54 }
55 } else {
56 ApplicationInfo {
57 app_name: String::new(),
58 app_version: 0,
59 engine_name: String::new(),
60 engine_version: 0,
61 api_version: VK_API_VERSION_1_0,
62 }
63 };
64
65 if app_info.api_version > VK_API_VERSION_1_3 {
67 return VkResult::ErrorIncompatibleDriver;
68 }
69
70 let mut extensions = Vec::new();
72 for i in 0..create_info.enabledExtensionCount {
73 let ext_name = *create_info.ppEnabledExtensionNames.add(i as usize);
74 if let Some(name) = c_str_to_string(ext_name) {
75 log::warn!("Extension requested but not supported: {}", name);
77 extensions.push(name);
79 }
80 }
81
82 let handle = INSTANCE_COUNTER.fetch_add(1, Ordering::SeqCst);
84
85 let instance_data = InstanceData {
87 app_info,
88 enabled_extensions: extensions,
89 };
90
91 INSTANCES.lock().unwrap().insert(handle, instance_data);
92
93 *pInstance = VkInstance::from_raw(handle);
95
96 log::info!("Created Kronos instance {:?} - compute-only, no ICD", handle);
97
98 VkResult::Success
99}
100
101#[no_mangle]
103pub unsafe extern "C" fn vkDestroyInstance(
104 instance: VkInstance,
105 _pAllocator: *const VkAllocationCallbacks,
106) {
107 if instance.is_null() {
108 return;
109 }
110
111 let handle = instance.as_raw();
112 INSTANCES.lock().unwrap().remove(&handle);
113
114 log::info!("Destroyed Kronos instance {:?}", handle);
115}
116
117#[no_mangle]
119pub unsafe extern "C" fn vkEnumeratePhysicalDevices(
120 instance: VkInstance,
121 pPhysicalDeviceCount: *mut u32,
122 pPhysicalDevices: *mut VkPhysicalDevice,
123) -> VkResult {
124 if instance.is_null() || pPhysicalDeviceCount.is_null() {
125 return VkResult::ErrorInitializationFailed;
126 }
127
128 let handle = instance.as_raw();
130 if !INSTANCES.lock().unwrap().contains_key(&handle) {
131 return VkResult::ErrorDeviceLost;
132 }
133
134 if pPhysicalDevices.is_null() {
136 *pPhysicalDeviceCount = 1;
137 return VkResult::Success;
138 }
139
140 let count = *pPhysicalDeviceCount;
141 if count == 0 {
142 return VkResult::Incomplete;
143 }
144
145 *pPhysicalDevices = VkPhysicalDevice::from_raw(1); *pPhysicalDeviceCount = 1;
148
149 VkResult::Success
150}
151
152unsafe fn c_str_to_string(ptr: *const i8) -> Option<String> {
154 if ptr.is_null() {
155 return None;
156 }
157 std::ffi::CStr::from_ptr(ptr)
158 .to_str()
159 .ok()
160 .map(|s| s.to_string())
161}