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