use anyhow::Result; use std::{collections::HashMap, ffi::c_void, mem, ptr}; use vulkan_rs::prelude::*; static mut FN_HANDLES: Option = None; pub fn vk_handles() -> &'static VkTypedefHandles { unsafe { FN_HANDLES.as_ref().unwrap() } } pub fn vk_handles_mut() -> &'static mut VkTypedefHandles { unsafe { FN_HANDLES.as_mut().unwrap() } } pub fn set_vk_handles(handles: VkTypedefHandles) { unsafe { FN_HANDLES = Some(handles) }; } pub struct VkTypedefHandles { typedefs: Vec, functions: HashMap, } impl VkTypedefHandles { pub fn new() -> Result { Ok(Self { typedefs: include_str!("../vk_functions") .lines() .map(|s| s.to_string()) .collect(), functions: HashMap::new(), }) } pub fn load_instance_functions( &mut self, instance: VkInstance, proc_addr: PFN_vkGetInstanceProcAddr, ) { unsafe { for symbol in &self.typedefs { let name = VkString::new(symbol); let function = proc_addr(instance, name.as_ptr()); if mem::transmute::(function) != ptr::null() { self.functions.insert(symbol.clone(), function); } } } } pub fn load_device_functions(&mut self, device: VkDevice, proc_addr: PFN_vkGetDeviceProcAddr) { unsafe { for symbol in &self.typedefs { let name = VkString::new(symbol); let function = proc_addr(device, name.as_ptr()); if mem::transmute::(function) != ptr::null() { self.functions.insert(symbol.clone(), function); } } } } pub fn handle(&self, symbol_name: impl ToString) -> Option { self.functions.get(&symbol_name.to_string()).cloned() } }