use std::ffi::CStr;
use std::fmt::{Debug, Display, Error, Formatter};
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
pub type VkSampleMask = u32;
pub type VkFlags = u32;
pub type VkDeviceSize = u64;
pub type VkDeviceAddress = u64;
#[cfg(target_family = "windows")]
pub type HANDLE = usize;
#[cfg(target_family = "windows")]
pub type HINSTANCE = usize;
#[cfg(target_family = "windows")]
pub type HWND = usize;
#[cfg(target_family = "windows")]
pub type LPCWSTR = *const u16;
#[cfg(target_family = "windows")]
pub type DWORD = u32;
#[cfg(target_family = "windows")]
#[allow(non_camel_case_types)]
pub type SECURITY_ATTRIBUTES = c_void;
macro_rules! handle {
($name:ident, $type:ty$(,$type_enum_variant:path)?) => {
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct $name($type);
impl $name {
$(
pub const TYPE: VkObjectType = $type_enum_variant;
)?
pub fn none() -> Self {
$name(<$type>::none())
}
}
impl Default for $name {
fn default() -> Self {
$name::none()
}
}
impl Display for $name {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", self.0.to_string())
}
}
impl From<$name> for u64 {
fn from(handle: $name) -> Self {
handle.0.into()
}
}
};
}
#[macro_export]
macro_rules! link_vulkan_structures {
{
$($first:ident).+
=>
$(#[$last_attr:meta])*
$($last:ident).+
} => {
{
$(#[$last_attr])*
{
$($first).+.pNext = std::mem::transmute(&$($last).+);
}
}
};
{
$($first:ident).+
=>
$(
$(#[$other_attr:meta])*
$($other:ident).+
),+
=>
$(#[$last_attr:meta])*
$($last:ident).+
}=>{
{
let mut last_next: &mut *mut std::ffi::c_void = std::mem::transmute(&mut $($first).+.pNext);
$(
$(#[$other_attr])*
{
*last_next = std::mem::transmute(&$($other).+);
last_next = std::mem::transmute(&mut $($other).+.pNext);
}
)+
$(#[$last_attr])*
{
*last_next = std::mem::transmute(&$($last).+);
}
}
}
}
macro_rules! enums {
(
$(
$(#[$enum_attr:meta])*
enum $enum_name:ident{
$(
$(#[$variant_attr:meta])*
$variant_name:ident = $value:literal
),*$(,)?
}
),*$(,)?
)=>{
$(
$(#[$enum_attr])*
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum $enum_name{
$(
$(#[$variant_attr])*
$variant_name = $value,
)*
}
)*
}
}
macro_rules! bitmasks {
(
$(
$(#[$flags_attr:meta])*
$flags_name:ident = enum $flag_bits_name:ident{
$(
$(#[$inner:ident $($args:tt)*])*
$bit_name:ident = $value:literal
),*$(,)?
}
),*$(,)?
)=>{
$(
bitflags! {
$(#[$flags_attr])*
#[repr(transparent)]
#[derive(Default)]
pub struct $flag_bits_name: u32 {
$(
$(#[$inner $($args)*])*
const $bit_name = $value;
)*
}
}
pub type $flags_name = $flag_bits_name;
)*
};
}
macro_rules! instance_level_functions {
(
$(
$(#[$function_attr:meta])*
fn $function_name:ident($($parameter_name:ident:$parameter_type:ty),*)$(->$return_type:ty)?;
)*
)=>{
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct InstanceLevelFunctions {
$(
$(#[$function_attr])*
pub $function_name: extern "C" fn($($parameter_name:$parameter_type),*)$(->$return_type)?,
)*
}
impl InstanceLevelFunctions {
pub fn load_from_instance(instance: crate::core::VkInstance)->InstanceLevelFunctions {
use std::ffi::CStr;
use std::mem::transmute;
use crate::get_instance_proc_addr;
unsafe {
let functions = InstanceLevelFunctions {
$(
$(#[$function_attr])*
$function_name: match get_instance_proc_addr(
instance,
CStr::from_bytes_with_nul_unchecked(concat!(stringify!($function_name), '\0').as_bytes()))
{
Ok(proc_addr) => transmute(proc_addr),
Err(_) => {
extern "C" fn $function_name($(_:$parameter_type),*)$(->$return_type)?{
unimplemented!()
}
$function_name
},
},
)*
};
functions
}
}
$(
$(#[$function_attr])*
#[inline(always)]
pub unsafe fn $function_name(&self, $($parameter_name:$parameter_type),*)$(->$return_type)?{
(self.$function_name)($($parameter_name),*)
}
)*
}
}
}
macro_rules! device_level_functions {
(
$(
$(#[$function_attr:meta])*
fn $function_name:ident($($parameter_name:ident:$parameter_type:ty),*)$(->$return_type:ty)?;
)*
)=>{
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct DeviceLevelFunctions {
$(
$(#[$function_attr])*
pub $function_name: extern "C" fn($($parameter_name:$parameter_type),*)$(->$return_type)?,
)*
}
impl DeviceLevelFunctions {
pub fn load_from_instance(instance: crate::core::VkInstance)->DeviceLevelFunctions {
use std::ffi::CStr;
use std::mem::transmute;
use crate::get_instance_proc_addr;
unsafe {
let functions = DeviceLevelFunctions {
$(
$(#[$function_attr])*
$function_name: match get_instance_proc_addr(
instance,
CStr::from_bytes_with_nul_unchecked(concat!(stringify!($function_name), '\0').as_bytes()))
{
Ok(proc_addr) => transmute(proc_addr),
Err(_) => {
extern "C" fn $function_name($(_:$parameter_type),*)$(->$return_type)?{
unimplemented!()
}
$function_name
},
},
)*
};
functions
}
}
pub fn load_from_device(core_functions: &crate::core::InstanceLevelFunctions, device: crate::core::VkDevice)->DeviceLevelFunctions {
use std::ffi::CStr;
use std::mem::transmute;
use crate::get_device_proc_addr;
unsafe {
let functions = DeviceLevelFunctions {
$(
$(#[$function_attr])*
$function_name: match get_device_proc_addr(
core_functions,
device,
CStr::from_bytes_with_nul_unchecked(concat!(stringify!($function_name), '\0').as_bytes()))
{
Ok(proc_addr) => transmute(proc_addr),
Err(_) => {
extern "C" fn $function_name($(_:$parameter_type),*)$(->$return_type)?{
unimplemented!()
}
$function_name
},
},
)*
};
functions
}
}
$(
$(#[$function_attr])*
#[inline(always)]
pub unsafe fn $function_name(&self, $($parameter_name:$parameter_type),*)$(->$return_type)?{
(self.$function_name)($($parameter_name),*)
}
)*
}
}
}
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct DispatchableHandle(usize);
impl DispatchableHandle {
pub fn none() -> Self {
DispatchableHandle(0)
}
}
impl Display for DispatchableHandle {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{:#x}", self.0)
}
}
impl From<DispatchableHandle> for u64 {
fn from(handle: DispatchableHandle) -> Self {
handle.0 as u64
}
}
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct NonDispatchableHandle(u64);
impl NonDispatchableHandle {
pub fn none() -> Self {
NonDispatchableHandle(0)
}
}
impl Display for NonDispatchableHandle {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", self.0)
}
}
impl From<NonDispatchableHandle> for u64 {
fn from(handle: NonDispatchableHandle) -> Self {
handle.0
}
}
pub const VK_MAX_PHYSICAL_DEVICE_NAME_SIZE: usize = 256;
pub const VK_UUID_SIZE: usize = 16;
pub const VK_LUID_SIZE: usize = 8;
pub const VK_MAX_EXTENSION_NAME_SIZE: usize = 256;
pub const VK_MAX_DESCRIPTION_SIZE: usize = 256;
pub const VK_MAX_MEMORY_TYPES: usize = 32;
pub const VK_MAX_MEMORY_HEAPS: usize = 16;
pub const VK_LOD_CLAMP_NONE: f32 = 1000f32;
pub const VK_REMAINING_MIP_LEVELS: u32 = 0xFFFF_FFFF;
pub const VK_REMAINING_ARRAY_LAYERS: u32 = 0xFFFF_FFFF;
pub const VK_WHOLE_SIZE: u64 = 0xFFFF_FFFF_FFFF_FFFF;
pub const VK_ATTACHMENT_UNUSED: u32 = 0xFFFF_FFFF;
pub const VK_SHADER_UNUSED_KHR: u32 = 0xFFFF_FFFF;
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct VkBool32(u32);
impl VkBool32 {
pub const TRUE: VkBool32 = VkBool32(1);
pub const FALSE: VkBool32 = VkBool32(0);
}
impl Default for VkBool32 {
#[inline(always)]
fn default() -> Self {
VkBool32::FALSE
}
}
impl From<VkBool32> for bool {
#[inline(always)]
fn from(bool: VkBool32) -> Self {
bool == VkBool32::TRUE
}
}
impl From<bool> for VkBool32 {
#[inline(always)]
fn from(bool: bool) -> Self {
VkBool32(bool as u32)
}
}
impl Debug for VkBool32 {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(
f,
"{}",
if *self == VkBool32::TRUE {
"VkBool32::TRUE"
} else {
"VkBool32::FALSE"
}
)
}
}
impl Display for VkBool32 {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "{}", *self == VkBool32::TRUE)
}
}
pub const VK_QUEUE_FAMILY_IGNORED: u32 = 0xFFFF_FFFF;
pub const VK_QUEUE_FAMILY_EXTERNAL: u32 = VK_QUEUE_FAMILY_IGNORED - 1;
pub const VK_SUBPASS_EXTERNAL: u32 = 0xFFFF_FFFF;
pub const VK_MAX_DEVICE_GROUP_SIZE: usize = 32;
pub const VK_MAX_DRIVER_NAME_SIZE: usize = 256;
pub const VK_MAX_DRIVER_INFO_SIZE: usize = 256;
#[derive(Debug)]
pub struct LoadingError(String);
fn get_instance_proc_addr(
instance: VkInstance,
name: &CStr,
) -> Result<PFN_vkVoidFunction, LoadingError> {
let function_pointer = vkGetInstanceProcAddr(instance, name.as_ptr());
match function_pointer as usize {
0 => Err(LoadingError(format!(
"Load function \"{}\" failed!",
name.to_str().unwrap()
))),
_ => Ok(function_pointer),
}
}
fn get_device_proc_addr(
core_functions: &InstanceLevelFunctions,
device: VkDevice,
name: &CStr,
) -> Result<PFN_vkVoidFunction, LoadingError> {
let function_pointer = unsafe { core_functions.vkGetDeviceProcAddr(device, name.as_ptr()) };
match function_pointer as usize {
0 => Err(LoadingError(format!(
"Load function '{}' failed!",
name.to_str().unwrap()
))),
_ => Ok(function_pointer),
}
}
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct ApiVersion(u32);
impl ApiVersion {
#[inline(always)]
pub const fn new(major: u32, minor: u32, patch: u32) -> ApiVersion {
ApiVersion((major << 22) | ((minor & 0x0000_03FF) << 12) | (patch & 0x0000_0FFF))
}
#[inline(always)]
pub fn major(&self) -> u32 {
(self.0 & 0xFFC0_0000) >> 22
}
#[inline(always)]
pub fn minor(&self) -> u32 {
(self.0 & 0x003F_F000) >> 12
}
#[inline(always)]
pub fn patch(&self) -> u32 {
self.0 & 0x0000_0FFF
}
}
impl From<u32> for ApiVersion {
#[inline(always)]
fn from(api_version: u32) -> Self {
ApiVersion(api_version)
}
}
impl Into<u32> for ApiVersion {
#[inline(always)]
fn into(self) -> u32 {
self.0
}
}
impl Display for ApiVersion {
#[inline(always)]
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}.{}.{}", self.major(), self.minor(), self.patch())
}
}
use std::os::raw::c_void;
mod core;
mod ext;
mod khr;
#[cfg(feature = "VulkanMemoryAllocator")]
mod vma;
pub use crate::core::*;
#[cfg(feature = "VK_EXT_debug_utils")]
pub use crate::ext::debug_utils::*;
#[cfg(feature = "VK_EXT_index_type_uint8")]
pub use crate::ext::index_type_uint8::*;
#[cfg(feature = "VK_EXT_memory_budget")]
pub use crate::ext::memory_budget::*;
#[cfg(feature = "VK_KHR_external_fence_fd")]
pub use crate::khr::external_fence_fd::*;
#[cfg(feature = "VK_KHR_external_fence_win32")]
pub use crate::khr::external_fence_win32::*;
#[cfg(feature = "VK_KHR_pipeline_library")]
pub use crate::khr::pipeline_library::*;
#[cfg(feature = "VK_KHR_deferred_host_operations")]
pub use crate::khr::deferred_host_operations::*;
#[cfg(feature = "VK_KHR_surface")]
pub use crate::khr::surface::*;
#[cfg(feature = "VK_KHR_swapchain")]
pub use crate::khr::swapchain::*;
#[cfg(feature = "VK_KHR_win32_surface")]
pub use crate::khr::win32_surface::*;
#[cfg(feature = "VK_KHR_acceleration_structure")]
pub use crate::khr::acceleration_structure::*;
#[cfg(feature = "VK_KHR_ray_tracing_pipeline")]
pub use crate::khr::ray_tracing_pipeline::*;
#[cfg(feature = "VK_KHR_ray_query")]
pub use crate::khr::ray_query::*;
#[cfg(feature = "VulkanMemoryAllocator")]
pub use vma::*;