1 use crate::prelude::*; 2 use crate::vk; 3 use crate::{Device, Entry, Instance}; 4 use std::ffi::CStr; 5 use std::mem; 6 7 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_EXT_full_screen_exclusive.html> 8 #[derive(Clone)] 9 pub struct FullScreenExclusive { 10 handle: vk::Device, 11 fp: vk::ExtFullScreenExclusiveFn, 12 } 13 14 impl FullScreenExclusive { 15 /// # Warning 16 /// [`Instance`] functions cannot be loaded from a [`Device`] and will always panic when called: 17 /// - [`Self::get_physical_device_surface_present_modes2()`] 18 /// 19 /// Load this struct using an [`Instance`] instead via [`Self::new_from_instance()`] if the 20 /// above [`Instance`] function is called. This will be solved in the next breaking `ash` 21 /// release: <https://github.com/ash-rs/ash/issues/727>. new(instance: &Instance, device: &Device) -> Self22 pub fn new(instance: &Instance, device: &Device) -> Self { 23 let handle = device.handle(); 24 let fp = vk::ExtFullScreenExclusiveFn::load(|name| unsafe { 25 mem::transmute(instance.get_device_proc_addr(handle, name.as_ptr())) 26 }); 27 Self { handle, fp } 28 } 29 30 /// Loads all functions on the [`Instance`] instead of [`Device`]. This incurs an extra 31 /// dispatch table for [`Device`] functions but also allows the [`Instance`] function to be 32 /// loaded instead of always panicking. See also [`Self::new()`] for more details. 33 /// 34 /// It is okay to pass [`vk::Device::null()`] when this struct is only used to call the 35 /// [`Instance`] function. new_from_instance(entry: &Entry, instance: &Instance, device: vk::Device) -> Self36 pub fn new_from_instance(entry: &Entry, instance: &Instance, device: vk::Device) -> Self { 37 let fp = vk::ExtFullScreenExclusiveFn::load(|name| unsafe { 38 mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr())) 39 }); 40 Self { handle: device, fp } 41 } 42 43 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkAcquireFullScreenExclusiveModeEXT.html> 44 #[inline] acquire_full_screen_exclusive_mode( &self, swapchain: vk::SwapchainKHR, ) -> VkResult<()>45 pub unsafe fn acquire_full_screen_exclusive_mode( 46 &self, 47 swapchain: vk::SwapchainKHR, 48 ) -> VkResult<()> { 49 (self.fp.acquire_full_screen_exclusive_mode_ext)(self.handle, swapchain).result() 50 } 51 52 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceSurfacePresentModes2EXT.html> 53 /// 54 /// # Warning 55 /// 56 /// Function will always panic unless this struct is loaded via [`Self::new_from_instance()`]. 57 #[inline] get_physical_device_surface_present_modes2( &self, physical_device: vk::PhysicalDevice, surface_info: &vk::PhysicalDeviceSurfaceInfo2KHR, ) -> VkResult<Vec<vk::PresentModeKHR>>58 pub unsafe fn get_physical_device_surface_present_modes2( 59 &self, 60 physical_device: vk::PhysicalDevice, 61 surface_info: &vk::PhysicalDeviceSurfaceInfo2KHR, 62 ) -> VkResult<Vec<vk::PresentModeKHR>> { 63 read_into_uninitialized_vector(|count, data| { 64 (self.fp.get_physical_device_surface_present_modes2_ext)( 65 physical_device, 66 surface_info, 67 count, 68 data, 69 ) 70 }) 71 } 72 73 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkReleaseFullScreenExclusiveModeEXT.html> 74 #[inline] release_full_screen_exclusive_mode( &self, swapchain: vk::SwapchainKHR, ) -> VkResult<()>75 pub unsafe fn release_full_screen_exclusive_mode( 76 &self, 77 swapchain: vk::SwapchainKHR, 78 ) -> VkResult<()> { 79 (self.fp.release_full_screen_exclusive_mode_ext)(self.handle, swapchain).result() 80 } 81 82 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDeviceGroupSurfacePresentModes2EXT.html> 83 #[inline] get_device_group_surface_present_modes2( &self, surface_info: &vk::PhysicalDeviceSurfaceInfo2KHR, ) -> VkResult<vk::DeviceGroupPresentModeFlagsKHR>84 pub unsafe fn get_device_group_surface_present_modes2( 85 &self, 86 surface_info: &vk::PhysicalDeviceSurfaceInfo2KHR, 87 ) -> VkResult<vk::DeviceGroupPresentModeFlagsKHR> { 88 let mut present_modes = mem::zeroed(); 89 (self.fp.get_device_group_surface_present_modes2_ext)( 90 self.handle, 91 surface_info, 92 &mut present_modes, 93 ) 94 .result_with_success(present_modes) 95 } 96 97 #[inline] name() -> &'static CStr98 pub const fn name() -> &'static CStr { 99 vk::ExtFullScreenExclusiveFn::name() 100 } 101 102 #[inline] fp(&self) -> &vk::ExtFullScreenExclusiveFn103 pub fn fp(&self) -> &vk::ExtFullScreenExclusiveFn { 104 &self.fp 105 } 106 107 #[inline] device(&self) -> vk::Device108 pub fn device(&self) -> vk::Device { 109 self.handle 110 } 111 } 112