91 lines
2.5 KiB
Rust
91 lines
2.5 KiB
Rust
|
use anyhow::Result;
|
||
|
use std::{collections::HashMap, ffi::c_void, fs, mem, path::Path, ptr};
|
||
|
use vulkan_sys::prelude::*;
|
||
|
|
||
|
static mut FN_HANDLES: Option<VkTypedefHandles> = 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<String>,
|
||
|
functions: HashMap<String, PFN_vkVoidFunction>,
|
||
|
instance: VkInstance,
|
||
|
device: VkDevice,
|
||
|
}
|
||
|
|
||
|
impl VkTypedefHandles {
|
||
|
pub fn new(symbol_files: &[impl AsRef<Path>]) -> Result<Self> {
|
||
|
let mut symbols = Vec::new();
|
||
|
|
||
|
for symbol_file in symbol_files {
|
||
|
let s = fs::read_to_string(symbol_file)?;
|
||
|
|
||
|
symbols.append(&mut s.lines().map(|s| s.to_string()).collect());
|
||
|
}
|
||
|
|
||
|
Ok(Self {
|
||
|
typedefs: symbols,
|
||
|
functions: HashMap::new(),
|
||
|
|
||
|
instance: VkInstance::NULL_HANDLE,
|
||
|
device: VkDevice::NULL_HANDLE,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
pub fn load_instance_functions(
|
||
|
&mut self,
|
||
|
instance: VkInstance,
|
||
|
proc_addr: PFN_vkGetInstanceProcAddr,
|
||
|
) {
|
||
|
self.instance = instance;
|
||
|
|
||
|
unsafe {
|
||
|
for symbol in &self.typedefs {
|
||
|
let name = VkString::new(symbol);
|
||
|
let function = proc_addr(instance, name.as_ptr());
|
||
|
|
||
|
if mem::transmute::<PFN_vkVoidFunction, *const c_void>(function) != ptr::null() {
|
||
|
self.functions.insert(symbol.clone(), function);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn load_device_functions(&mut self, device: VkDevice, proc_addr: PFN_vkGetDeviceProcAddr) {
|
||
|
self.device = device;
|
||
|
|
||
|
unsafe {
|
||
|
for symbol in &self.typedefs {
|
||
|
let name = VkString::new(symbol);
|
||
|
let function = proc_addr(device, name.as_ptr());
|
||
|
|
||
|
if mem::transmute::<PFN_vkVoidFunction, *const c_void>(function) != ptr::null() {
|
||
|
self.functions.insert(symbol.clone(), function);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn handle(&self, symbol_name: impl ToString) -> Option<PFN_vkVoidFunction> {
|
||
|
self.functions.get(&symbol_name.to_string()).cloned()
|
||
|
}
|
||
|
|
||
|
pub fn instance(&self) -> VkInstance {
|
||
|
self.instance
|
||
|
}
|
||
|
|
||
|
pub fn device(&self) -> VkDevice {
|
||
|
self.device
|
||
|
}
|
||
|
}
|