diff --git a/src/dummy_functions.rs b/src/dummy_functions.rs index 1145113..652e436 100644 --- a/src/dummy_functions.rs +++ b/src/dummy_functions.rs @@ -17,13 +17,6 @@ pub type PFN_vkGetPhysicalDeviceExternalFenceProperties = PFN_vkVoidFunction; pub type PFN_vkGetPhysicalDeviceExternalSemaphoreProperties = PFN_vkVoidFunction; pub type PFN_vkGetPhysicalDeviceToolProperties = PFN_vkVoidFunction; pub type PFN_vkGetPhysicalDevicePresentRectanglesKHR = PFN_vkVoidFunction; -pub type PFN_vkGetPhysicalDeviceDisplayPropertiesKHR = PFN_vkVoidFunction; -pub type PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR = PFN_vkVoidFunction; -pub type PFN_vkGetDisplayPlaneSupportedDisplaysKHR = PFN_vkVoidFunction; -pub type PFN_vkGetDisplayModePropertiesKHR = PFN_vkVoidFunction; -pub type PFN_vkCreateDisplayModeKHR = PFN_vkVoidFunction; -pub type PFN_vkGetDisplayPlaneCapabilitiesKHR = PFN_vkVoidFunction; -pub type PFN_vkCreateDisplayPlaneSurfaceKHR = PFN_vkVoidFunction; pub type PFN_vkEnumeratePhysicalDeviceGroupsKHR = PFN_vkVoidFunction; pub type PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR = PFN_vkVoidFunction; pub type PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = PFN_vkVoidFunction; diff --git a/src/lib.rs b/src/lib.rs index 0aece7a..4eba5af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,12 +4,82 @@ pub mod layer_device_dispatch_table; pub mod layer_instance_dispatch_table; pub mod structs; -use std::{fs::OpenOptions, io::Write, mem, os::raw::c_char, ptr}; +use std::{ + fs::OpenOptions, + io::Write, + mem::{self}, + os::raw::c_char, + ptr, +}; use enums::*; use structs::*; use vulkan_sys::prelude::*; +static mut INSTANCE_FN_HANDLES: Option = None; + +fn instance_fns() -> &'static VkFunctionHandles { + unsafe { INSTANCE_FN_HANDLES.as_ref().unwrap() } +} + +pub struct VkFunctionHandles { + pub static_functions: StaticFunctions, + pub entry_functions: EntryFunctions, + + pub instance_functions: InstanceFunctions, + pub instance_wsi_functions: InstanceWSIFunctions, + pub physical_device_properties2_functions: PhysicalDeviceProperties2Functions, + pub debug_report_callback_functions: DebugReportCallbackFunctions, + pub debug_utils_messenger_functions: DebugUtilsMessengerFunctions, +} + +impl VkFunctionHandles { + pub fn load_instance( + static_functions: StaticFunctions, + entry_functions: EntryFunctions, + instance: VkInstance, + ) -> Self { + Self { + instance_functions: InstanceFunctions::new(&static_functions, instance), + instance_wsi_functions: InstanceWSIFunctions::new(&static_functions, instance), + physical_device_properties2_functions: PhysicalDeviceProperties2Functions::new( + &static_functions, + instance, + ), + debug_report_callback_functions: DebugReportCallbackFunctions::new( + &static_functions, + instance, + ), + debug_utils_messenger_functions: DebugUtilsMessengerFunctions::new( + &static_functions, + instance, + ), + + static_functions, + entry_functions, + } + } +} + +macro_rules! cmp_vk_fn { + ($name:ident, {$([$fns:ident, $fn_name:ident],)*}) => { + match $name { + $( + stringify!($fn_name) => return unsafe { + mem::transmute( + instance_fns() + .$fns + .$fn_name, + ) + }, + )* + + _ => () + } + + } +} + #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn vkNegotiateLoaderLayerInterfaceVersion( @@ -38,27 +108,9 @@ extern "system" fn get_device_proc_addr( device: VkDevice, function_name: *const c_char, ) -> PFN_vkVoidFunction { - write_log("vulkan layer device proc addr"); + write_log("-> vulkan layer device proc addr"); - let func_string = match VkString::try_from(function_name) { - Ok(func) => func, - Err(_) => { - write_log("Err: failed creating string"); - return Functions::Null.convert(); - } - }; - - write_log(format!("requested function: {}", func_string.as_str())); - - match func_string.as_str() { - "vkCreateDevice" => Functions::CreateDevice(create_device), - "vkDestroyDevice" => Functions::DestroyDevice(destroy_device), - "vkCreateInstance" => Functions::CreateInstance(create_instance), - "vkDestroyInstance" => Functions::DestroyInstance(destroy_instance), - - _ => Functions::Null, - } - .convert() + get_function(function_name) } #[no_mangle] @@ -66,8 +118,12 @@ extern "system" fn get_instance_proc_addr( instance: VkInstance, function_name: *const c_char, ) -> PFN_vkVoidFunction { - write_log("vulkan layer instance proc addr"); + write_log("-> vulkan layer instance proc addr"); + get_function(function_name) +} + +fn get_function(function_name: *const c_char) -> PFN_vkVoidFunction { let func_string = match VkString::try_from(function_name) { Ok(func) => func, Err(_) => { @@ -76,13 +132,61 @@ extern "system" fn get_instance_proc_addr( } }; - match func_string.as_str() { + let s = func_string.as_str(); + + cmp_vk_fn!(s, { + [debug_utils_messenger_functions, vkCreateDebugUtilsMessengerEXT], + [debug_utils_messenger_functions, vkDestroyDebugUtilsMessengerEXT], + [debug_report_callback_functions, vkCreateDebugReportCallbackEXT], + [debug_report_callback_functions, vkDestroyDebugReportCallbackEXT], + [instance_functions, vkEnumeratePhysicalDevices], + [instance_functions, vkGetPhysicalDeviceFeatures], + [instance_functions, vkGetPhysicalDeviceFormatProperties], + [instance_functions, vkGetPhysicalDeviceImageFormatProperties], + [instance_functions, vkGetPhysicalDeviceProperties], + [instance_functions, vkGetPhysicalDeviceQueueFamilyProperties], + [instance_functions, vkGetPhysicalDeviceMemoryProperties], + [instance_functions, vkEnumerateDeviceExtensionProperties], + // [instance_functions, vkEnumerateDeviceLayerProperties], + [instance_functions, vkGetPhysicalDeviceSparseImageFormatProperties], + // [instance_functions, vkEnumeratePhysicalDeviceGroups], + [physical_device_properties2_functions, vkGetPhysicalDeviceFeatures2KHR], + [physical_device_properties2_functions, vkGetPhysicalDeviceProperties2KHR], + [physical_device_properties2_functions, vkGetPhysicalDeviceFormatProperties2KHR], + [physical_device_properties2_functions, vkGetPhysicalDeviceFeatures2KHR], + [physical_device_properties2_functions, vkGetPhysicalDeviceFeatures2KHR], + [instance_wsi_functions, vkDestroySurfaceKHR], + [instance_wsi_functions, vkGetPhysicalDeviceSurfaceSupportKHR], + [instance_wsi_functions, vkGetPhysicalDeviceSurfaceCapabilitiesKHR], + [instance_wsi_functions, vkGetPhysicalDeviceSurfaceFormatsKHR], + [instance_wsi_functions, vkGetPhysicalDeviceSurfacePresentModesKHR], + [instance_wsi_functions, vkGetPhysicalDeviceDisplayPropertiesKHR], + [instance_wsi_functions, vkGetPhysicalDeviceDisplayPlanePropertiesKHR], + [instance_wsi_functions, vkGetDisplayPlaneSupportedDisplaysKHR], + [instance_wsi_functions, vkGetDisplayModePropertiesKHR], + [instance_wsi_functions, vkCreateDisplayModeKHR], + [instance_wsi_functions, vkGetDisplayPlaneCapabilitiesKHR], + [instance_wsi_functions, vkCreateDisplayPlaneSurfaceKHR], + [instance_wsi_functions, vkCreateXlibSurfaceKHR], + [instance_wsi_functions, vkGetPhysicalDeviceXlibPresentationSupportKHR], + [instance_wsi_functions, vkCreateXcbSurfaceKHR], + [instance_wsi_functions, vkGetPhysicalDeviceXcbPresentationSupportKHR], + [instance_wsi_functions, vkCreateWaylandSurfaceKHR], + [instance_wsi_functions, vkGetPhysicalDeviceWaylandPresentationSupportKHR], + } + ); + + match s { "vkCreateDevice" => Functions::CreateDevice(create_device), "vkDestroyDevice" => Functions::DestroyDevice(destroy_device), "vkCreateInstance" => Functions::CreateInstance(create_instance), "vkDestroyInstance" => Functions::DestroyInstance(destroy_instance), - _ => Functions::Null, + _ => { + write_log(format!("\trequested fn: {}", s)); + write_log(format!("\t-> not found")); + Functions::Null + } } .convert() } @@ -92,7 +196,7 @@ extern "system" fn create_instance( allocator: *const VkAllocationCallbacks, instance: *mut VkInstance, ) -> VkResult { - write_log("vulkan layer create instance"); + write_log(" ================== vulkan layer create instance =================="); let chain_info = match VkLayerInstanceCreateInfo::get_chain_info( unsafe { &*create_info }, @@ -106,29 +210,31 @@ extern "system" fn create_instance( }; let proc_addr = chain_info.layer_info().next_instance_proc_addr; - let create_instance = match unsafe { - mem::transmute::>(proc_addr( - VkInstance::NULL_HANDLE, - VkString::new("vkCreateInstance").as_ptr(), - )) - } { - Some(pfn) => pfn, - None => return VK_ERROR_INITIALIZATION_FAILED, + + let static_functions = StaticFunctions { + _lib: None, + vkGetInstanceProcAddr: proc_addr, }; + let entry_functions = EntryFunctions::new(&static_functions); chain_info.advance_layer_info(); - let result = create_instance(create_info, allocator, instance); + let result = unsafe { entry_functions.vkCreateInstance(create_info, allocator, instance) }; if result != VK_SUCCESS { return result; } - write_log("successfully created instance."); + let function_handles = + VkFunctionHandles::load_instance(static_functions, entry_functions, unsafe { *instance }); + + unsafe { INSTANCE_FN_HANDLES = Some(function_handles) }; + + write_log("-> successfully created instance."); VK_SUCCESS } extern "system" fn destroy_instance(instance: VkInstance, allocator: *const VkAllocationCallbacks) { - write_log("vulkan layer destroy instance"); + write_log(" ================== vulkan layer destroy instance =================="); } extern "system" fn create_device( @@ -137,13 +243,13 @@ extern "system" fn create_device( allocator: *const VkAllocationCallbacks, device: *mut VkDevice, ) -> VkResult { - write_log("vulkan layer create device"); + write_log(" ================== vulkan layer create device =================="); VK_SUCCESS } extern "system" fn destroy_device(device: VkDevice, allocator: *const VkAllocationCallbacks) { - write_log("vulkan layer destroy device"); + write_log(" ================== vulkan layer destroy device =================="); } fn write_log(msg: impl ToString) {