1 #[cfg(doc)] 2 use super::Swapchain; 3 use crate::prelude::*; 4 use crate::vk; 5 use crate::{Device, Entry, Instance}; 6 use std::ffi::CStr; 7 use std::mem; 8 9 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_device_group.html> 10 #[derive(Clone)] 11 pub struct DeviceGroup { 12 handle: vk::Device, 13 fp: vk::KhrDeviceGroupFn, 14 } 15 16 impl DeviceGroup { 17 /// # Warning 18 /// [`Instance`] functions cannot be loaded from a [`Device`] and will always panic when called: 19 /// - [`Self::get_physical_device_present_rectangles()`] 20 /// 21 /// Load this struct using an [`Instance`] instead via [`Self::new_from_instance()`] if the 22 /// above [`Instance`] function is called. This will be solved in the next breaking `ash` 23 /// release: <https://github.com/ash-rs/ash/issues/727>. new(instance: &Instance, device: &Device) -> Self24 pub fn new(instance: &Instance, device: &Device) -> Self { 25 let handle = device.handle(); 26 let fp = vk::KhrDeviceGroupFn::load(|name| unsafe { 27 mem::transmute(instance.get_device_proc_addr(handle, name.as_ptr())) 28 }); 29 Self { handle, fp } 30 } 31 32 /// Loads all functions on the [`Instance`] instead of [`Device`]. This incurs an extra 33 /// dispatch table for [`Device`] functions but also allows the [`Instance`] function to be 34 /// loaded instead of always panicking. See also [`Self::new()`] for more details. 35 /// 36 /// It is okay to pass [`vk::Device::null()`] when this struct is only used to call the 37 /// [`Instance`] function. new_from_instance(entry: &Entry, instance: &Instance, device: vk::Device) -> Self38 pub fn new_from_instance(entry: &Entry, instance: &Instance, device: vk::Device) -> Self { 39 let fp = vk::KhrDeviceGroupFn::load(|name| unsafe { 40 mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr())) 41 }); 42 Self { handle: device, fp } 43 } 44 45 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDeviceGroupPeerMemoryFeaturesKHR.html> 46 #[inline] get_device_group_peer_memory_features( &self, heap_index: u32, local_device_index: u32, remote_device_index: u32, ) -> vk::PeerMemoryFeatureFlags47 pub unsafe fn get_device_group_peer_memory_features( 48 &self, 49 heap_index: u32, 50 local_device_index: u32, 51 remote_device_index: u32, 52 ) -> vk::PeerMemoryFeatureFlags { 53 let mut peer_memory_features = mem::zeroed(); 54 (self.fp.get_device_group_peer_memory_features_khr)( 55 self.handle, 56 heap_index, 57 local_device_index, 58 remote_device_index, 59 &mut peer_memory_features, 60 ); 61 peer_memory_features 62 } 63 64 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdSetDeviceMaskKHR.html> 65 #[inline] cmd_set_device_mask(&self, command_buffer: vk::CommandBuffer, device_mask: u32)66 pub unsafe fn cmd_set_device_mask(&self, command_buffer: vk::CommandBuffer, device_mask: u32) { 67 (self.fp.cmd_set_device_mask_khr)(command_buffer, device_mask) 68 } 69 70 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdDispatchBaseKHR.html> 71 #[inline] cmd_dispatch_base( &self, command_buffer: vk::CommandBuffer, base_group: (u32, u32, u32), group_count: (u32, u32, u32), )72 pub unsafe fn cmd_dispatch_base( 73 &self, 74 command_buffer: vk::CommandBuffer, 75 base_group: (u32, u32, u32), 76 group_count: (u32, u32, u32), 77 ) { 78 (self.fp.cmd_dispatch_base_khr)( 79 command_buffer, 80 base_group.0, 81 base_group.1, 82 base_group.2, 83 group_count.0, 84 group_count.1, 85 group_count.2, 86 ) 87 } 88 89 /// Requires [`VK_KHR_surface`] to be enabled. 90 /// 91 /// Also available as [`Swapchain::get_device_group_present_capabilities()`] since [Vulkan 1.1]. 92 /// 93 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDeviceGroupPresentCapabilitiesKHR.html> 94 /// 95 /// [Vulkan 1.1]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_VERSION_1_1.html 96 /// [`VK_KHR_surface`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_surface.html 97 #[inline] get_device_group_present_capabilities( &self, device_group_present_capabilities: &mut vk::DeviceGroupPresentCapabilitiesKHR, ) -> VkResult<()>98 pub unsafe fn get_device_group_present_capabilities( 99 &self, 100 device_group_present_capabilities: &mut vk::DeviceGroupPresentCapabilitiesKHR, 101 ) -> VkResult<()> { 102 (self.fp.get_device_group_present_capabilities_khr)( 103 self.handle, 104 device_group_present_capabilities, 105 ) 106 .result() 107 } 108 109 /// Requires [`VK_KHR_surface`] to be enabled. 110 /// 111 /// Also available as [`Swapchain::get_device_group_surface_present_modes()`] since [Vulkan 1.1]. 112 /// 113 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDeviceGroupSurfacePresentModesKHR.html> 114 /// 115 /// [Vulkan 1.1]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_VERSION_1_1.html 116 /// [`VK_KHR_surface`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_surface.html 117 #[inline] get_device_group_surface_present_modes( &self, surface: vk::SurfaceKHR, ) -> VkResult<vk::DeviceGroupPresentModeFlagsKHR>118 pub unsafe fn get_device_group_surface_present_modes( 119 &self, 120 surface: vk::SurfaceKHR, 121 ) -> VkResult<vk::DeviceGroupPresentModeFlagsKHR> { 122 let mut modes = mem::zeroed(); 123 (self.fp.get_device_group_surface_present_modes_khr)(self.handle, surface, &mut modes) 124 .result_with_success(modes) 125 } 126 127 /// Requires [`VK_KHR_surface`] to be enabled. 128 /// 129 /// Also available as [`Swapchain::get_physical_device_present_rectangles()`] since [Vulkan 1.1]. 130 /// 131 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDevicePresentRectanglesKHR.html> 132 /// 133 /// [Vulkan 1.1]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_VERSION_1_1.html 134 /// [`VK_KHR_surface`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_surface.html 135 /// 136 /// # Warning 137 /// 138 /// Function will always panic unless this struct is loaded via [`Self::new_from_instance()`]. 139 #[inline] get_physical_device_present_rectangles( &self, physical_device: vk::PhysicalDevice, surface: vk::SurfaceKHR, ) -> VkResult<Vec<vk::Rect2D>>140 pub unsafe fn get_physical_device_present_rectangles( 141 &self, 142 physical_device: vk::PhysicalDevice, 143 surface: vk::SurfaceKHR, 144 ) -> VkResult<Vec<vk::Rect2D>> { 145 read_into_uninitialized_vector(|count, data| { 146 (self.fp.get_physical_device_present_rectangles_khr)( 147 physical_device, 148 surface, 149 count, 150 data, 151 ) 152 }) 153 } 154 155 /// On success, returns the next image's index and whether the swapchain is suboptimal for the surface. 156 /// 157 /// Requires [`VK_KHR_swapchain`] to be enabled. 158 /// 159 /// Also available as [`Swapchain::acquire_next_image2()`] since [Vulkan 1.1]. 160 /// 161 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkAcquireNextImage2KHR.html> 162 /// 163 /// [Vulkan 1.1]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_VERSION_1_1.html 164 /// [`VK_KHR_swapchain`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_swapchain.html 165 #[inline] acquire_next_image2( &self, acquire_info: &vk::AcquireNextImageInfoKHR, ) -> VkResult<(u32, bool)>166 pub unsafe fn acquire_next_image2( 167 &self, 168 acquire_info: &vk::AcquireNextImageInfoKHR, 169 ) -> VkResult<(u32, bool)> { 170 let mut index = 0; 171 let err_code = (self.fp.acquire_next_image2_khr)(self.handle, acquire_info, &mut index); 172 match err_code { 173 vk::Result::SUCCESS => Ok((index, false)), 174 vk::Result::SUBOPTIMAL_KHR => Ok((index, true)), 175 _ => Err(err_code), 176 } 177 } 178 179 #[inline] name() -> &'static CStr180 pub const fn name() -> &'static CStr { 181 vk::KhrDeviceGroupFn::name() 182 } 183 184 #[inline] fp(&self) -> &vk::KhrDeviceGroupFn185 pub fn fp(&self) -> &vk::KhrDeviceGroupFn { 186 &self.fp 187 } 188 189 #[inline] device(&self) -> vk::Device190 pub fn device(&self) -> vk::Device { 191 self.handle 192 } 193 } 194