1#[cfg(all(
7 test,
8 feature = "hwdevice",
9 any(target_os = "linux", target_os = "windows", target_os = "macos")
10))]
11mod conformance;
12mod context;
13#[allow(
20 dead_code,
21 non_camel_case_types,
22 unreachable_pub,
23 clippy::all,
24 clippy::pedantic,
25 clippy::undocumented_unsafe_blocks
26)]
27mod interop {
28 include!(concat!(env!("OUT_DIR"), "/interop.rs"));
29}
30
31const _: () = {
36 use interop::{
37 Alpha2D3D12CopyInfo as D3D12, Alpha2D3D12EncodeCaps as Caps,
38 Alpha2D3D12EncodeCopy as Encode, Alpha2MetalFrameInfo as Metal,
39 };
40 use std::mem::{align_of, offset_of, size_of};
41 assert!(size_of::<D3D12>() == 40 && align_of::<D3D12>() == 8);
42 assert!(offset_of!(D3D12, resource) == 0);
43 assert!(offset_of!(D3D12, fence) == 8);
44 assert!(offset_of!(D3D12, fence_value) == 16);
45 assert!(offset_of!(D3D12, width) == 24);
46 assert!(offset_of!(D3D12, height) == 28);
47 assert!(offset_of!(D3D12, dxgi_format) == 32);
48 assert!(size_of::<Encode>() == 48 && align_of::<Encode>() == 8);
49 assert!(offset_of!(Encode, luma) == 0);
50 assert!(offset_of!(Encode, chroma) == 8);
51 assert!(offset_of!(Encode, destination) == 16);
52 assert!(offset_of!(Encode, frame_fence) == 24);
53 assert!(offset_of!(Encode, frame_value) == 32);
54 assert!(offset_of!(Encode, width) == 40);
55 assert!(offset_of!(Encode, height) == 44);
56 assert!(size_of::<Caps>() == 76 && align_of::<Caps>() == 4);
57 assert!(offset_of!(Caps, supported) == 0);
58 assert!(offset_of!(Caps, refused_check) == 4);
59 assert!(offset_of!(Caps, refused_status) == 8);
60 assert!(offset_of!(Caps, validation_flags) == 12);
61 assert!(offset_of!(Caps, min_width) == 16);
62 assert!(offset_of!(Caps, min_height) == 20);
63 assert!(offset_of!(Caps, max_width) == 24);
64 assert!(offset_of!(Caps, max_height) == 28);
65 assert!(offset_of!(Caps, width_multiple) == 32);
66 assert!(offset_of!(Caps, height_multiple) == 36);
67 assert!(offset_of!(Caps, max_p_l0_references) == 40);
68 assert!(offset_of!(Caps, max_b_l0_references) == 44);
69 assert!(offset_of!(Caps, max_l1_references) == 48);
70 assert!(offset_of!(Caps, rate_control_modes) == 52);
71 assert!(offset_of!(Caps, refused_rate_control_modes) == 56);
72 assert!(offset_of!(Caps, rate_control_status) == 60);
73 assert!(size_of::<Metal>() == 56 && align_of::<Metal>() == 8);
74 assert!(offset_of!(Metal, width) == 0);
75 assert!(offset_of!(Metal, height) == 4);
76 assert!(offset_of!(Metal, plane_width) == 8);
77 assert!(offset_of!(Metal, plane_height) == 16);
78 assert!(offset_of!(Metal, clean_x) == 24);
79 assert!(offset_of!(Metal, clean_y) == 28);
80 assert!(offset_of!(Metal, clean_width) == 32);
81 assert!(offset_of!(Metal, clean_height) == 36);
82 assert!(offset_of!(Metal, pixel_format) == 40);
83 assert!(offset_of!(Metal, io_surface) == 48);
84};
85#[cfg(all(target_os = "windows", feature = "hwdevice"))]
86mod d3d12;
87mod import;
88mod lifetime;
89#[cfg(all(target_os = "macos", feature = "hwdevice"))]
90mod metal;
91#[cfg(feature = "hwdevice")]
92mod status;
93mod surface_budget;
94mod sync;
95#[cfg(all(target_os = "linux", feature = "hwdevice"))]
96mod vulkan;
97
98pub use context::NativeGpuIdentity;
99#[cfg(all(target_os = "windows", feature = "hwdevice"))]
100pub use d3d12::{
101 D3D12AdapterIdentity, D3D12CopyLease, D3D12EncodeCodec, D3D12EncodeCopier, D3D12EncodeExtent,
102 ImportedD3D12Frame, SharedD3D12Context, SharedD3D12Error, d3d12_adapter_identity,
103 gpu_wait_timeout as d3d12_wait_timeout,
104};
105pub use import::{ImportedPlaneDescriptor, NativePlaneLayout};
106pub use lifetime::{NativeSurfaceLease, SurfaceIdentity};
107#[cfg(all(target_os = "macos", feature = "hwdevice"))]
108pub use metal::{
109 ImportedMetalFrame, MetalEncoderPlanes, MetalImportLease, SharedMetalContext, SharedMetalError,
110 gpu_wait_timeout as metal_wait_timeout,
111};
112pub use surface_budget::{SurfaceBudget, SurfaceBudgetError, SurfaceReservation, SurfaceUsage};
113pub use sync::{ExternalSyncPoint, NativeImageState};
114#[cfg(all(target_os = "linux", feature = "hwdevice"))]
115pub use vulkan::{
116 ImportTicketStats, ImportedVulkanFrame, SharedVulkanContext, SharedVulkanError,
117 VideoEncodeExtent, VulkanEncodeCopier, VulkanImportLease, VulkanLayerVersion,
118 probe_vulkan_submission, shared_device_index,
119};
120
121pub fn set_gpu_wait_timeout(timeout: std::time::Duration) {
128 #[cfg(all(target_os = "linux", feature = "hwdevice"))]
129 vulkan::set_wait_timeout(timeout);
130 #[cfg(all(target_os = "windows", feature = "hwdevice"))]
131 d3d12::set_wait_timeout(timeout);
132 #[cfg(all(target_os = "macos", feature = "hwdevice"))]
133 metal::set_wait_timeout(timeout);
134 let _ = timeout;
135}
136
137#[cfg_attr(
142 not(all(target_os = "windows", feature = "hwdevice")),
143 allow(dead_code)
144)]
145fn win32_wait_milliseconds(timeout: std::time::Duration) -> u32 {
146 const INFINITE: u32 = u32::MAX;
147 u32::try_from(timeout.as_millis())
148 .unwrap_or(INFINITE)
149 .min(INFINITE - 1)
150}
151
152#[cfg(test)]
153mod tests {
154 use std::time::Duration;
155
156 #[test]
157 fn no_wait_timeout_reaches_win32_as_infinite() {
158 let milliseconds =
159 |value: u64| super::win32_wait_milliseconds(Duration::from_millis(value));
160 assert_eq!(milliseconds(30_000), 30_000);
161 assert_eq!(milliseconds(u64::from(u32::MAX) - 1), u32::MAX - 1);
162 assert_eq!(milliseconds(u64::from(u32::MAX)), u32::MAX - 1);
163 assert_eq!(milliseconds(u64::from(u32::MAX) + 1), u32::MAX - 1);
164 assert_eq!(milliseconds(u64::MAX), u32::MAX - 1);
165 assert_eq!(super::win32_wait_milliseconds(Duration::MAX), u32::MAX - 1);
166 assert_eq!(
168 super::win32_wait_milliseconds(Duration::from_micros(999)),
169 0
170 );
171 }
172}