#[cfg(doc)] use super::Entry; use crate::device::Device; use crate::prelude::*; use crate::vk; use crate::RawPtr; use std::mem; use std::os::raw::c_char; use std::ptr; /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkInstance.html> #[derive(Clone)] pub struct Instance { pub(crate) handle: vk::Instance, pub(crate) instance_fn_1_0: vk::InstanceFnV1_0, pub(crate) instance_fn_1_1: vk::InstanceFnV1_1, pub(crate) instance_fn_1_2: vk::InstanceFnV1_2, pub(crate) instance_fn_1_3: vk::InstanceFnV1_3, } impl Instance { pub unsafe fn load(static_fn: &vk::StaticFn, instance: vk::Instance) -> Self { let load_fn = |name: &std::ffi::CStr| { mem::transmute((static_fn.get_instance_proc_addr)(instance, name.as_ptr())) }; Self { handle: instance, instance_fn_1_0: vk::InstanceFnV1_0::load(load_fn), instance_fn_1_1: vk::InstanceFnV1_1::load(load_fn), instance_fn_1_2: vk::InstanceFnV1_2::load(load_fn), instance_fn_1_3: vk::InstanceFnV1_3::load(load_fn), } } #[inline] pub fn handle(&self) -> vk::Instance { self.handle } } /// Vulkan core 1.3 #[allow(non_camel_case_types)] impl Instance { #[inline] pub fn fp_v1_3(&self) -> &vk::InstanceFnV1_3 { &self.instance_fn_1_3 } /// Retrieve the number of elements to pass to [`get_physical_device_tool_properties()`][Self::get_physical_device_tool_properties()] #[inline] pub unsafe fn get_physical_device_tool_properties_len( &self, physical_device: vk::PhysicalDevice, ) -> VkResult<usize> { let mut count = 0; (self.instance_fn_1_3.get_physical_device_tool_properties)( physical_device, &mut count, ptr::null_mut(), ) .result_with_success(count as usize) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceToolProperties.html> /// /// Call [`get_physical_device_tool_properties_len()`][Self::get_physical_device_tool_properties_len()] to query the number of elements to pass to `out`. /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer. #[inline] pub unsafe fn get_physical_device_tool_properties( &self, physical_device: vk::PhysicalDevice, out: &mut [vk::PhysicalDeviceToolProperties], ) -> VkResult<()> { let mut count = out.len() as u32; (self.instance_fn_1_3.get_physical_device_tool_properties)( physical_device, &mut count, out.as_mut_ptr(), ) .result()?; assert_eq!(count as usize, out.len()); Ok(()) } } /// Vulkan core 1.2 #[allow(non_camel_case_types)] impl Instance { #[inline] pub fn fp_v1_2(&self) -> &vk::InstanceFnV1_2 { &self.instance_fn_1_2 } } /// Vulkan core 1.1 #[allow(non_camel_case_types)] impl Instance { #[inline] pub fn fp_v1_1(&self) -> &vk::InstanceFnV1_1 { &self.instance_fn_1_1 } /// Retrieve the number of elements to pass to [`enumerate_physical_device_groups()`][Self::enumerate_physical_device_groups()] #[inline] pub unsafe fn enumerate_physical_device_groups_len(&self) -> VkResult<usize> { let mut group_count = 0; (self.instance_fn_1_1.enumerate_physical_device_groups)( self.handle(), &mut group_count, ptr::null_mut(), ) .result_with_success(group_count as usize) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumeratePhysicalDeviceGroups.html> /// /// Call [`enumerate_physical_device_groups_len()`][Self::enumerate_physical_device_groups_len()] to query the number of elements to pass to `out`. /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer. #[inline] pub unsafe fn enumerate_physical_device_groups( &self, out: &mut [vk::PhysicalDeviceGroupProperties], ) -> VkResult<()> { let mut count = out.len() as u32; (self.instance_fn_1_1.enumerate_physical_device_groups)( self.handle(), &mut count, out.as_mut_ptr(), ) .result()?; assert_eq!(count as usize, out.len()); Ok(()) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFeatures2.html> #[inline] pub unsafe fn get_physical_device_features2( &self, physical_device: vk::PhysicalDevice, features: &mut vk::PhysicalDeviceFeatures2, ) { (self.instance_fn_1_1.get_physical_device_features2)(physical_device, features); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceProperties2.html> #[inline] pub unsafe fn get_physical_device_properties2( &self, physical_device: vk::PhysicalDevice, prop: &mut vk::PhysicalDeviceProperties2, ) { (self.instance_fn_1_1.get_physical_device_properties2)(physical_device, prop); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFormatProperties2.html> #[inline] pub unsafe fn get_physical_device_format_properties2( &self, physical_device: vk::PhysicalDevice, format: vk::Format, out: &mut vk::FormatProperties2, ) { (self.instance_fn_1_1.get_physical_device_format_properties2)(physical_device, format, out); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceImageFormatProperties2.html> #[inline] pub unsafe fn get_physical_device_image_format_properties2( &self, physical_device: vk::PhysicalDevice, format_info: &vk::PhysicalDeviceImageFormatInfo2, image_format_prop: &mut vk::ImageFormatProperties2, ) -> VkResult<()> { (self .instance_fn_1_1 .get_physical_device_image_format_properties2)( physical_device, format_info, image_format_prop, ) .result() } /// Retrieve the number of elements to pass to [`get_physical_device_queue_family_properties2()`][Self::get_physical_device_queue_family_properties2()] #[inline] pub unsafe fn get_physical_device_queue_family_properties2_len( &self, physical_device: vk::PhysicalDevice, ) -> usize { let mut queue_count = 0; (self .instance_fn_1_1 .get_physical_device_queue_family_properties2)( physical_device, &mut queue_count, ptr::null_mut(), ); queue_count as usize } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceQueueFamilyProperties2.html> /// /// Call [`get_physical_device_queue_family_properties2_len()`][Self::get_physical_device_queue_family_properties2_len()] to query the number of elements to pass to `out`. /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer. #[inline] pub unsafe fn get_physical_device_queue_family_properties2( &self, physical_device: vk::PhysicalDevice, out: &mut [vk::QueueFamilyProperties2], ) { let mut count = out.len() as u32; (self .instance_fn_1_1 .get_physical_device_queue_family_properties2)( physical_device, &mut count, out.as_mut_ptr(), ); assert_eq!(count as usize, out.len()); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceMemoryProperties2.html> #[inline] pub unsafe fn get_physical_device_memory_properties2( &self, physical_device: vk::PhysicalDevice, out: &mut vk::PhysicalDeviceMemoryProperties2, ) { (self.instance_fn_1_1.get_physical_device_memory_properties2)(physical_device, out); } /// Retrieve the number of elements to pass to [`get_physical_device_sparse_image_format_properties2()`][Self::get_physical_device_sparse_image_format_properties2()] #[inline] pub unsafe fn get_physical_device_sparse_image_format_properties2_len( &self, physical_device: vk::PhysicalDevice, format_info: &vk::PhysicalDeviceSparseImageFormatInfo2, ) -> usize { let mut format_count = 0; (self .instance_fn_1_1 .get_physical_device_sparse_image_format_properties2)( physical_device, format_info, &mut format_count, ptr::null_mut(), ); format_count as usize } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceSparseImageFormatProperties2.html> /// /// Call [`get_physical_device_sparse_image_format_properties2_len()`][Self::get_physical_device_sparse_image_format_properties2_len()] to query the number of elements to pass to `out`. /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer. #[inline] pub unsafe fn get_physical_device_sparse_image_format_properties2( &self, physical_device: vk::PhysicalDevice, format_info: &vk::PhysicalDeviceSparseImageFormatInfo2, out: &mut [vk::SparseImageFormatProperties2], ) { let mut count = out.len() as u32; (self .instance_fn_1_1 .get_physical_device_sparse_image_format_properties2)( physical_device, format_info, &mut count, out.as_mut_ptr(), ); assert_eq!(count as usize, out.len()); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceExternalBufferProperties.html> #[inline] pub unsafe fn get_physical_device_external_buffer_properties( &self, physical_device: vk::PhysicalDevice, external_buffer_info: &vk::PhysicalDeviceExternalBufferInfo, out: &mut vk::ExternalBufferProperties, ) { (self .instance_fn_1_1 .get_physical_device_external_buffer_properties)( physical_device, external_buffer_info, out, ); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceExternalFenceProperties.html> #[inline] pub unsafe fn get_physical_device_external_fence_properties( &self, physical_device: vk::PhysicalDevice, external_fence_info: &vk::PhysicalDeviceExternalFenceInfo, out: &mut vk::ExternalFenceProperties, ) { (self .instance_fn_1_1 .get_physical_device_external_fence_properties)( physical_device, external_fence_info, out, ); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceExternalSemaphoreProperties.html> #[inline] pub unsafe fn get_physical_device_external_semaphore_properties( &self, physical_device: vk::PhysicalDevice, external_semaphore_info: &vk::PhysicalDeviceExternalSemaphoreInfo, out: &mut vk::ExternalSemaphoreProperties, ) { (self .instance_fn_1_1 .get_physical_device_external_semaphore_properties)( physical_device, external_semaphore_info, out, ); } } /// Vulkan core 1.0 #[allow(non_camel_case_types)] impl Instance { #[inline] pub fn fp_v1_0(&self) -> &vk::InstanceFnV1_0 { &self.instance_fn_1_0 } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateDevice.html> /// /// # Safety /// /// There is a [parent/child relation] between [`Instance`] and the resulting [`Device`]. The /// application must not [destroy][Instance::destroy_instance()] the parent [`Instance`] object /// before first [destroying][Device::destroy_device()] the returned [`Device`] child object. /// [`Device`] does _not_ implement [drop][drop()] semantics and can only be destroyed via /// [`destroy_device()`][Device::destroy_device()]. /// /// See the [`Entry::create_instance()`] documentation for more destruction ordering rules on /// [`Instance`]. /// /// [parent/child relation]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#fundamentals-objectmodel-lifetime #[inline] pub unsafe fn create_device( &self, physical_device: vk::PhysicalDevice, create_info: &vk::DeviceCreateInfo, allocation_callbacks: Option<&vk::AllocationCallbacks>, ) -> VkResult<Device> { let mut device = mem::zeroed(); (self.instance_fn_1_0.create_device)( physical_device, create_info, allocation_callbacks.as_raw_ptr(), &mut device, ) .result()?; Ok(Device::load(&self.instance_fn_1_0, device)) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDeviceProcAddr.html> #[inline] pub unsafe fn get_device_proc_addr( &self, device: vk::Device, p_name: *const c_char, ) -> vk::PFN_vkVoidFunction { (self.instance_fn_1_0.get_device_proc_addr)(device, p_name) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkDestroyInstance.html> #[inline] pub unsafe fn destroy_instance(&self, allocation_callbacks: Option<&vk::AllocationCallbacks>) { (self.instance_fn_1_0.destroy_instance)(self.handle(), allocation_callbacks.as_raw_ptr()); } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFormatProperties.html> #[inline] pub unsafe fn get_physical_device_format_properties( &self, physical_device: vk::PhysicalDevice, format: vk::Format, ) -> vk::FormatProperties { let mut format_prop = mem::zeroed(); (self.instance_fn_1_0.get_physical_device_format_properties)( physical_device, format, &mut format_prop, ); format_prop } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceImageFormatProperties.html> #[inline] pub unsafe fn get_physical_device_image_format_properties( &self, physical_device: vk::PhysicalDevice, format: vk::Format, typ: vk::ImageType, tiling: vk::ImageTiling, usage: vk::ImageUsageFlags, flags: vk::ImageCreateFlags, ) -> VkResult<vk::ImageFormatProperties> { let mut image_format_prop = mem::zeroed(); (self .instance_fn_1_0 .get_physical_device_image_format_properties)( physical_device, format, typ, tiling, usage, flags, &mut image_format_prop, ) .result_with_success(image_format_prop) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceMemoryProperties.html> #[inline] pub unsafe fn get_physical_device_memory_properties( &self, physical_device: vk::PhysicalDevice, ) -> vk::PhysicalDeviceMemoryProperties { let mut memory_prop = mem::zeroed(); (self.instance_fn_1_0.get_physical_device_memory_properties)( physical_device, &mut memory_prop, ); memory_prop } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceProperties.html> #[inline] pub unsafe fn get_physical_device_properties( &self, physical_device: vk::PhysicalDevice, ) -> vk::PhysicalDeviceProperties { let mut prop = mem::zeroed(); (self.instance_fn_1_0.get_physical_device_properties)(physical_device, &mut prop); prop } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceQueueFamilyProperties.html> #[inline] pub unsafe fn get_physical_device_queue_family_properties( &self, physical_device: vk::PhysicalDevice, ) -> Vec<vk::QueueFamilyProperties> { read_into_uninitialized_vector(|count, data| { (self .instance_fn_1_0 .get_physical_device_queue_family_properties)( physical_device, count, data ); vk::Result::SUCCESS }) // The closure always returns SUCCESS .unwrap() } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFeatures.html> #[inline] pub unsafe fn get_physical_device_features( &self, physical_device: vk::PhysicalDevice, ) -> vk::PhysicalDeviceFeatures { let mut prop = mem::zeroed(); (self.instance_fn_1_0.get_physical_device_features)(physical_device, &mut prop); prop } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumeratePhysicalDevices.html> #[inline] pub unsafe fn enumerate_physical_devices(&self) -> VkResult<Vec<vk::PhysicalDevice>> { read_into_uninitialized_vector(|count, data| { (self.instance_fn_1_0.enumerate_physical_devices)(self.handle(), count, data) }) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateDeviceExtensionProperties.html> #[inline] pub unsafe fn enumerate_device_extension_properties( &self, device: vk::PhysicalDevice, ) -> VkResult<Vec<vk::ExtensionProperties>> { read_into_uninitialized_vector(|count, data| { (self.instance_fn_1_0.enumerate_device_extension_properties)( device, ptr::null(), count, data, ) }) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateDeviceLayerProperties.html> #[inline] pub unsafe fn enumerate_device_layer_properties( &self, device: vk::PhysicalDevice, ) -> VkResult<Vec<vk::LayerProperties>> { read_into_uninitialized_vector(|count, data| { (self.instance_fn_1_0.enumerate_device_layer_properties)(device, count, data) }) } /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceSparseImageFormatProperties.html> #[inline] pub unsafe fn get_physical_device_sparse_image_format_properties( &self, physical_device: vk::PhysicalDevice, format: vk::Format, typ: vk::ImageType, samples: vk::SampleCountFlags, usage: vk::ImageUsageFlags, tiling: vk::ImageTiling, ) -> Vec<vk::SparseImageFormatProperties> { read_into_uninitialized_vector(|count, data| { (self .instance_fn_1_0 .get_physical_device_sparse_image_format_properties)( physical_device, format, typ, samples, usage, tiling, count, data, ); vk::Result::SUCCESS }) // The closure always returns SUCCESS .unwrap() } }