From f822c232cfd1a1a58d74a9ab7c714901d029602c Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 25 Sep 2018 20:36:28 -0700 Subject: [PATCH] declared ICD api --- .gitignore | 2 + Cargo.toml | 2 + vulkan-driver/Cargo.toml | 14 +++++ vulkan-driver/build.rs | 83 +++++++++++++++++++++++++++++ vulkan-driver/src/api.rs | 7 +++ vulkan-driver/src/lib.rs | 97 ++++++++++++++++++++++++++++++++++ vulkan-driver/vulkan-wrapper.h | 14 +++++ 7 files changed, 219 insertions(+) create mode 100644 Cargo.toml create mode 100644 vulkan-driver/Cargo.toml create mode 100644 vulkan-driver/build.rs create mode 100644 vulkan-driver/src/api.rs create mode 100644 vulkan-driver/src/lib.rs create mode 100644 vulkan-driver/vulkan-wrapper.h diff --git a/.gitignore b/.gitignore index e69de29..4fffb2f 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..6b0d8e8 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["vulkan-driver"] diff --git a/vulkan-driver/Cargo.toml b/vulkan-driver/Cargo.toml new file mode 100644 index 0000000..7a85b74 --- /dev/null +++ b/vulkan-driver/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "vulkan-driver" +version = "0.1.0" +authors = ["Jacob Lifshay "] + +[lib] +crate-type = ["cdylib"] + +[target.'cfg(unix)'.dependencies] +xcb = "0.8" + +[build-dependencies] +bindgen = "0.40" +regex = "1" diff --git a/vulkan-driver/build.rs b/vulkan-driver/build.rs new file mode 100644 index 0000000..4aa46c5 --- /dev/null +++ b/vulkan-driver/build.rs @@ -0,0 +1,83 @@ +extern crate bindgen; +extern crate regex; +use std::env; +use std::fs; +use std::io; +use std::path::PathBuf; + +fn detect_vulkan_calling_convention() -> io::Result { + let code = bindgen::builder() + .header_contents( + "vulkan_detect.h", + r#"#include +#ifdef __cplusplus +extern "C" { +#endif + +VKAPI_ATTR void VKAPI_CALL detect_fn(); + +#ifdef __cplusplus +} +#endif +"#, + ).clang_arg("-target") + .clang_arg(env::var("TARGET").unwrap()) + .clang_arg("-I../external/Vulkan-Headers/include") + .whitelist_function("detect_fn") + .generate() + .map_err(|_| io::Error::new(io::ErrorKind::Other, "generate() failed"))? + .to_string(); + if let Some(captures) = regex::Regex::new(r#"extern "([^"]+)""#) + .unwrap() + .captures(&code) + { + Ok(captures[1].to_owned()) + } else { + eprintln!("code:\n{}", code); + Err(io::Error::new(io::ErrorKind::Other, "regex not found")) + } +} + +fn main() -> io::Result<()> { + println!("cargo:rerun-if-changed=vulkan-wrapper.h"); + println!("cargo:rerun-if-changed=../external/Vulkan-Headers/include"); + let vulkan_calling_convention = detect_vulkan_calling_convention()?; + let match_calling_convention_regex = regex::Regex::new(r#"extern "([^"]+)""#).unwrap(); + let builder = bindgen::builder() + .header("vulkan-wrapper.h") + .clang_arg("-target") + .clang_arg(env::var("TARGET").unwrap()) + .clang_arg("-I../external/Vulkan-Headers/include") + .prepend_enum_name(false) + .layout_tests(false) + .whitelist_var("VK_.*") + .whitelist_var("ICD_LOADER_MAGIC") + .whitelist_type("Vk.*") + .whitelist_type("PFN_.*") + .blacklist_type("^xcb_.*") + .derive_debug(false) + .ignore_functions() + .constified_enum(".*"); + let mut code = builder + .generate() + .map_err(|_| io::Error::new(io::ErrorKind::Other, "generate() failed"))? + .to_string(); + code = match_calling_convention_regex + .replace_all(&code, |captures: ®ex::Captures| { + if captures[1] == vulkan_calling_convention { + r#"extern "system""# + } else { + let _ = fs::write( + PathBuf::from(env::var("OUT_DIR").unwrap()).join("vulkan-types.rs"), + &code, + ); + eprintln!("vulkan_calling_convention: {:?}", vulkan_calling_convention); + panic!("unhandled non-vulkan calling convention"); + } + }).into_owned(); + fs::write( + PathBuf::from(env::var("OUT_DIR").unwrap()).join("vulkan-types.rs"), + code, + )?; + Ok(()) +} diff --git a/vulkan-driver/src/api.rs b/vulkan-driver/src/api.rs new file mode 100644 index 0000000..ac2fce9 --- /dev/null +++ b/vulkan-driver/src/api.rs @@ -0,0 +1,7 @@ +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#[cfg(unix)] +use xcb::ffi::{xcb_connection_t, xcb_visualid_t, xcb_window_t}; +include!(concat!(env!("OUT_DIR"), "/vulkan-types.rs")); diff --git a/vulkan-driver/src/lib.rs b/vulkan-driver/src/lib.rs new file mode 100644 index 0000000..2b256a3 --- /dev/null +++ b/vulkan-driver/src/lib.rs @@ -0,0 +1,97 @@ +#[cfg(unix)] +extern crate xcb; +mod api; +use std::ffi::CStr; +use std::os::raw::c_char; + +#[no_mangle] +pub extern "system" fn vk_icdGetInstanceProcAddr( + instance: api::VkInstance, + name: *const c_char, +) -> api::PFN_vkVoidFunction { + unimplemented!() +} + +// note that if the following fails, then you may be encountering bindgen issue #1402 +// https://github.com/rust-lang-nursery/rust-bindgen/issues/1402 +#[allow(dead_code)] +const ASSERT_TYPE_VK_ICD_GET_INSTANCE_PROC_ADDR: api::PFN_vkGetInstanceProcAddr = + Some(vk_icdGetInstanceProcAddr); + +const ICD_VERSION: u32 = 5; + +#[no_mangle] +pub extern "system" fn vk_icdNegotiateLoaderICDInterfaceVersion( + supported_version: &mut u32, +) -> api::VkResult { + if *supported_version > ICD_VERSION { + *supported_version = ICD_VERSION; + } + api::VK_SUCCESS +} + +#[no_mangle] +pub extern "system" fn vk_icdGetPhysicalDeviceProcAddr( + instance: api::VkInstance, + name: *const c_char, +) -> api::PFN_vkVoidFunction { + match unsafe { CStr::from_ptr(name) }.to_str().ok()? { + "vkCreateDevice" + | "vkCreateDisplayModeKHR" + | "vkEnumerateDeviceExtensionProperties" + | "vkEnumerateDeviceLayerProperties" + | "vkGetDisplayModeProperties2KHR" + | "vkGetDisplayModePropertiesKHR" + | "vkGetDisplayPlaneCapabilities2KHR" + | "vkGetDisplayPlaneCapabilitiesKHR" + | "vkGetDisplayPlaneSupportedDisplaysKHR" + | "vkGetPhysicalDeviceDisplayPlaneProperties2KHR" + | "vkGetPhysicalDeviceDisplayPlanePropertiesKHR" + | "vkGetPhysicalDeviceDisplayProperties2KHR" + | "vkGetPhysicalDeviceDisplayPropertiesKHR" + | "vkGetPhysicalDeviceExternalBufferProperties" + | "vkGetPhysicalDeviceExternalBufferPropertiesKHR" + | "vkGetPhysicalDeviceExternalFenceProperties" + | "vkGetPhysicalDeviceExternalFencePropertiesKHR" + | "vkGetPhysicalDeviceExternalImageFormatPropertiesNV" + | "vkGetPhysicalDeviceExternalSemaphoreProperties" + | "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR" + | "vkGetPhysicalDeviceFeatures" + | "vkGetPhysicalDeviceFeatures2" + | "vkGetPhysicalDeviceFeatures2KHR" + | "vkGetPhysicalDeviceFormatProperties" + | "vkGetPhysicalDeviceFormatProperties2" + | "vkGetPhysicalDeviceFormatProperties2KHR" + | "vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX" + | "vkGetPhysicalDeviceImageFormatProperties" + | "vkGetPhysicalDeviceImageFormatProperties2" + | "vkGetPhysicalDeviceImageFormatProperties2KHR" + | "vkGetPhysicalDeviceMemoryProperties" + | "vkGetPhysicalDeviceMemoryProperties2" + | "vkGetPhysicalDeviceMemoryProperties2KHR" + | "vkGetPhysicalDeviceMultisamplePropertiesEXT" + | "vkGetPhysicalDevicePresentRectanglesKHR" + | "vkGetPhysicalDeviceProperties" + | "vkGetPhysicalDeviceProperties2" + | "vkGetPhysicalDeviceProperties2KHR" + | "vkGetPhysicalDeviceQueueFamilyProperties" + | "vkGetPhysicalDeviceQueueFamilyProperties2" + | "vkGetPhysicalDeviceQueueFamilyProperties2KHR" + | "vkGetPhysicalDeviceSparseImageFormatProperties" + | "vkGetPhysicalDeviceSparseImageFormatProperties2" + | "vkGetPhysicalDeviceSparseImageFormatProperties2KHR" + | "vkGetPhysicalDeviceSurfaceCapabilities2EXT" + | "vkGetPhysicalDeviceSurfaceCapabilities2KHR" + | "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" + | "vkGetPhysicalDeviceSurfaceFormats2KHR" + | "vkGetPhysicalDeviceSurfaceFormatsKHR" + | "vkGetPhysicalDeviceSurfacePresentModesKHR" + | "vkGetPhysicalDeviceSurfaceSupportKHR" + | "vkGetPhysicalDeviceXcbPresentationSupportKHR" + | "vkReleaseDisplayEXT" => vk_icdGetInstanceProcAddr(instance, name), + _ => None, + } +} + +#[cfg(test)] +mod tests {} diff --git a/vulkan-driver/vulkan-wrapper.h b/vulkan-driver/vulkan-wrapper.h new file mode 100644 index 0000000..9e95fbd --- /dev/null +++ b/vulkan-driver/vulkan-wrapper.h @@ -0,0 +1,14 @@ +#include +#ifdef __ANDROID__ +#error not supported on Android; need to fix ABI +#endif +#define VK_NO_PROTOTYPES +#include +#include +#ifdef __unix +typedef struct xcb_connection_t xcb_connection_t; +typedef uint32_t xcb_visualid_t; +typedef uint32_t xcb_window_t; +#include +#endif +#undef VK_NO_PROTOTYPES -- 2.30.2