ash/extensions/khr/device_group.rs
1#[cfg(doc)]
2use super::Swapchain;
3use crate::prelude::*;
4use crate::vk;
5use crate::{Device, Entry, Instance};
6use std::ffi::CStr;
7use std::mem;
8
9/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_device_group.html>
10#[derive(Clone)]
11pub struct DeviceGroup {
12 handle: vk::Device,
13 fp: vk::KhrDeviceGroupFn,
14}
15
16impl 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>.
24 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.
38 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]
47 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]
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]
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]
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]
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]
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]
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]
180 pub const fn name() -> &'static CStr {
181 vk::KhrDeviceGroupFn::name()
182 }
183
184 #[inline]
185 pub fn fp(&self) -> &vk::KhrDeviceGroupFn {
186 &self.fp
187 }
188
189 #[inline]
190 pub fn device(&self) -> vk::Device {
191 self.handle
192 }
193}