#![allow(non_snake_case)] use crate::enums::*; use vulkan_sys::prelude::*; use std::{ mem::{self, ManuallyDrop}, os::raw::{c_char, c_void}, }; #[allow(non_camel_case_types)] pub type PFN_GetPhysicalDeviceProcAddr = extern "system" fn(instance: VkInstance, pName: *const c_char); #[repr(C)] #[derive(Clone)] pub struct VkNegotiateLayerInterface { pub sType: VkNegotiateLayerStructType, pub pNext: *mut c_void, pub loaderLayerInterfaceVersion: u32, pub pfnGetInstanceProcAddr: Option, pub pfnGetDeviceProcAddr: Option, pub pfnGetPhysicalDeviceProcAddr: Option, } #[repr(C)] #[derive(Clone, Copy)] pub struct VkLayerInstanceInfo { pub instance_info: *mut c_void, pub next_instance_proc_addr: PFN_vkGetInstanceProcAddr, } #[repr(C)] #[derive(Clone, Copy)] pub struct VkLayerInstanceLink { pub next: *mut VkLayerInstanceLink, pub next_instance_proc_addr: PFN_vkGetInstanceProcAddr, } #[repr(C)] #[derive(Clone, Copy)] pub struct VkLayerDeviceInfo { pub device_info: *mut c_void, pub next_instance_proc_addr: PFN_vkGetInstanceProcAddr, } #[repr(C)] #[derive(Clone, Copy)] pub struct VkLayerDeviceLink { pub next: *mut VkLayerDeviceLink, pub next_instance_proc_addr: PFN_vkGetInstanceProcAddr, pub next_device_proc_addr: PFN_vkGetDeviceProcAddr, } #[repr(C)] #[derive(Clone, Copy)] pub union InstanceLayerInfo { pub layer_info: *const VkLayerInstanceLink, pub instance_info: ManuallyDrop, } #[repr(C)] #[derive(Clone)] pub struct VkLayerInstanceCreateInfo { pub sType: VkStructureType, pub next: *const c_void, pub function: VkLayerFunction, pub u: InstanceLayerInfo, } impl VkLayerInstanceCreateInfo { pub fn get_chain_info<'a>( create_info: &'a VkInstanceCreateInfo, function: VkLayerFunction, ) -> Option<&'a mut Self> { let mut chain_info: Option<&mut VkLayerInstanceCreateInfo> = unsafe { mem::transmute(create_info.pNext) }; loop { match &chain_info { Some(info) => { if info.sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && info.function == function { break; } else { chain_info = unsafe { mem::transmute(info.next) }; } } None => break, } } chain_info } pub fn layer_info(&self) -> &VkLayerInstanceLink { debug_assert!(self.function == VK_LAYER_LINK_INFO); unsafe { &*self.u.layer_info } } pub fn advance_layer_info(&mut self) { debug_assert!(self.function == VK_LAYER_LINK_INFO); unsafe { self.u.layer_info = (*self.u.layer_info).next } } } impl Drop for VkLayerInstanceCreateInfo { fn drop(&mut self) { // TODO manually drop self.u.instance_info } } #[repr(C)] #[derive(Clone, Copy)] pub union DeviceLayerInfo { pub layer_info: *const VkLayerDeviceLink, pub device_info: ManuallyDrop, } #[repr(C)] #[derive(Clone)] pub struct VkLayerDeviceCreateInfo { pub sType: VkStructureType, pub next: *const c_void, pub function: VkLayerFunction, pub u: DeviceLayerInfo, } impl VkLayerDeviceCreateInfo { pub fn get_chain_info<'a>( create_info: &'a VkDeviceCreateInfo, function: VkLayerFunction, ) -> Option<&'a mut Self> { let mut chain_info: Option<&mut VkLayerDeviceCreateInfo> = unsafe { mem::transmute(create_info.pNext) }; loop { match &chain_info { Some(info) => { if info.sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && info.function == function { break; } else { chain_info = unsafe { mem::transmute(info.next) }; } } None => break, } } chain_info } pub fn layer_info(&self) -> &VkLayerDeviceLink { debug_assert!(self.function == VK_LAYER_LINK_INFO); unsafe { &*self.u.layer_info } } } impl Drop for VkLayerDeviceCreateInfo { fn drop(&mut self) { // TODO manually drop self.u.device_info } }