• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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