Load symbols from vk headers

This commit is contained in:
hodasemi 2023-01-11 18:51:31 +01:00
parent b594bc3762
commit aaa0fe80cb
4 changed files with 73 additions and 19 deletions

2
.gitignore vendored
View file

@ -1,2 +1,4 @@
/target /target
/Cargo.lock /Cargo.lock
vk_functions

43
build.rs Normal file
View file

@ -0,0 +1,43 @@
use std::{fs::File, io::Write, path::Path, process::Command, str::from_utf8};
const VK_INCLUDE: &str = "/usr/include/vulkan";
const VK_HEADER: &[&str] = &[
"vulkan_core.h",
"vulkan_xcb.h",
"vulkan_xlib.h",
"vulkan_wayland.h",
];
const FN_PREFIX: &str = "PFN_";
fn main() {
let mut fns = Vec::new();
for header in VK_HEADER {
Command::new("ctags")
.arg("--help")
.output()
.expect("Failed to execute ctags. Maybe you need to install it first?");
let output = Command::new("ctags")
.arg("-x")
.arg("--c-types=t")
.arg(format!("{}/{}", VK_INCLUDE, header))
.output()
.expect(&format!("failed to open file {}/{}", VK_INCLUDE, header));
let output_splits = from_utf8(&output.stdout).unwrap().split_whitespace();
for split in output_splits {
if split.starts_with(FN_PREFIX) {
fns.push(split.trim_start_matches(FN_PREFIX).to_string())
}
}
}
let path = Path::new("vk_functions");
let mut file = File::create(path).unwrap();
for func in fns {
file.write_all(format!("{}\n", func).as_bytes()).unwrap();
}
}

View file

@ -40,15 +40,7 @@ pub extern "C" fn vkNegotiateLoaderLayerInterfaceVersion(
} }
}; };
set_vk_handles( set_vk_handles(VkTypedefHandles::new().unwrap());
VkTypedefHandles::new(&[
"vulkan_symbols/vulkan_core_symbols",
"vulkan_symbols/vulkan_wayland_symbols",
"vulkan_symbols/vulkan_xcb_symbols",
"vulkan_symbols/vulkan_xlib_symbols",
])
.unwrap(),
);
VK_SUCCESS VK_SUCCESS
} }
@ -77,6 +69,10 @@ extern "system" fn get_device_proc_addr(
_ => (), _ => (),
}; };
if let Some(func) = vk_handles().handle(s) {
return func;
}
write_log(format!("\trequested fn: {} in device proc addr", s)); write_log(format!("\trequested fn: {} in device proc addr", s));
write_log(format!("\t-> not found")); write_log(format!("\t-> not found"));
Functions::Null.convert() Functions::Null.convert()
@ -106,6 +102,10 @@ extern "system" fn get_instance_proc_addr(
_ => (), _ => (),
}; };
if let Some(func) = vk_handles().handle(s) {
return func;
}
write_log(format!("\trequested fn: {} in instance proc addr", s)); write_log(format!("\trequested fn: {} in instance proc addr", s));
write_log(format!("\t-> not found")); write_log(format!("\t-> not found"));
Functions::Null.convert() Functions::Null.convert()
@ -152,6 +152,13 @@ extern "system" fn create_instance(
extern "system" fn destroy_instance(instance: VkInstance, allocator: *const VkAllocationCallbacks) { extern "system" fn destroy_instance(instance: VkInstance, allocator: *const VkAllocationCallbacks) {
write_log(" ================== vulkan layer destroy instance =================="); write_log(" ================== vulkan layer destroy instance ==================");
unsafe {
let destroy_instance: PFN_vkDestroyInstance =
mem::transmute(vk_handles().handle("vkDestroyInstance").unwrap());
destroy_instance(instance, allocator);
}
} }
extern "system" fn create_device( extern "system" fn create_device(
@ -194,9 +201,16 @@ extern "system" fn create_device(
extern "system" fn destroy_device(device: VkDevice, allocator: *const VkAllocationCallbacks) { extern "system" fn destroy_device(device: VkDevice, allocator: *const VkAllocationCallbacks) {
write_log(" ================== vulkan layer destroy device =================="); write_log(" ================== vulkan layer destroy device ==================");
unsafe {
let destroy_device: PFN_vkDestroyDevice =
mem::transmute(vk_handles().handle("vkDestroyDevice").unwrap());
destroy_device(device, allocator);
}
} }
fn write_log(msg: impl ToString) { pub fn write_log(msg: impl ToString) {
let mut file = OpenOptions::new() let mut file = OpenOptions::new()
.append(true) .append(true)
.create(true) .create(true)

View file

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use std::{collections::HashMap, ffi::c_void, fs, mem, path::Path, ptr}; use std::{collections::HashMap, ffi::c_void, mem, ptr};
use vulkan_sys::prelude::*; use vulkan_sys::prelude::*;
static mut FN_HANDLES: Option<VkTypedefHandles> = None; static mut FN_HANDLES: Option<VkTypedefHandles> = None;
@ -24,14 +24,9 @@ pub struct VkTypedefHandles {
} }
impl VkTypedefHandles { impl VkTypedefHandles {
pub fn new(symbol_files: &[impl AsRef<Path>]) -> Result<Self> { pub fn new() -> Result<Self> {
let mut symbols = Vec::new(); let fns = include_str!("../vk_functions");
let symbols = fns.lines().map(|s| s.to_string()).collect();
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 { Ok(Self {
typedefs: symbols, typedefs: symbols,