Skip to main content

apple_metal/
exhaustive.rs

1#![allow(
2    clippy::module_name_repetitions,
3    clippy::too_many_lines,
4    clippy::type_complexity
5)]
6
7use crate::{
8    ffi,
9    util::{c_string, take_optional_string},
10    ComputePipelineState, DynamicLibrary, MetalDevice, MetalLibrary, RenderPipelineState,
11};
12use core::ffi::{c_char, c_void, CStr};
13use core::ptr;
14use core::sync::atomic::{AtomicBool, Ordering};
15use doom_fish_utils::callback_context::CallbackContext;
16use std::path::Path;
17use std::sync::{Mutex, PoisonError};
18
19macro_rules! opaque_symbol_handle {
20    ($(#[$meta:meta])* pub struct $name:ident;) => {
21        $(#[$meta])*
22/// Mirrors the `Metal` framework counterpart for this type.
23        pub struct $name {
24            ptr: *mut c_void,
25        }
26
27        // SAFETY: Metal ObjC objects use atomic reference counting and are safe
28        // to move across threads.  All `&self` methods on these types are either
29        // read-only or call ObjC methods documented as thread-safe by Apple.
30        unsafe impl Send for $name {}
31        unsafe impl Sync for $name {}
32
33        impl Drop for $name {
34            fn drop(&mut self) {
35                if !self.ptr.is_null() {
36                    unsafe { ffi::ametal_object_release(self.ptr) };
37                    self.ptr = ptr::null_mut();
38                }
39            }
40        }
41
42        impl $name {
43/// Mirrors the `Metal` framework constant `fn`.
44            #[must_use]
45            pub const fn as_ptr(&self) -> *mut c_void {
46                self.ptr
47            }
48
49            /// Wrap a raw, +1-retained opaque handle returned by the Swift bridge.
50            ///
51            /// # Safety
52            ///
53            /// `ptr` must be a valid, non-null, +1-retained Objective-C object pointer
54            /// whose ownership is being transferred to this value.  Passing a
55            /// pointer that is already owned by another instance causes a
56            /// double-release.
57            #[must_use]
58            pub unsafe fn from_raw(ptr: *mut c_void) -> Self {
59                Self { ptr }
60            }
61
62            #[allow(dead_code)]
63            fn wrap(ptr: *mut c_void) -> Option<Self> {
64                if ptr.is_null() {
65                    None
66                } else {
67                    Some(Self { ptr })
68                }
69            }
70
71/// Calls the `Metal` framework counterpart for `label`.
72            #[must_use]
73            pub fn label(&self) -> Option<String> {
74                unsafe { take_optional_string(ffi::ametal_object_copy_label(self.ptr)) }
75            }
76        }
77    };
78}
79
80macro_rules! opaque_symbol_class {
81    ($(#[$meta:meta])* pub struct $name:ident => $objc:literal;) => {
82        opaque_symbol_handle!(
83            $(#[$meta])*
84/// Mirrors the `Metal` framework counterpart for this type.
85            pub struct $name;
86        );
87
88        impl $name {
89/// Calls the `Metal` framework counterpart for `new`.
90            #[must_use]
91            pub fn new() -> Option<Self> {
92                Self::wrap(unsafe {
93                    ffi::ametal_new_class_instance(concat!($objc, "\0").as_ptr().cast())
94                })
95            }
96        }
97    };
98}
99
100macro_rules! raw_value_type {
101    ($(#[$meta:meta])* pub struct $name:ident($ty:ty);) => {
102        $(#[$meta])*
103/// Mirrors the `Metal` framework counterpart for this type.
104        #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
105        #[repr(transparent)]
106        pub struct $name(pub $ty);
107
108        impl $name {
109/// Mirrors the `Metal` framework constant `fn`.
110            #[must_use]
111            pub const fn from_raw(raw: $ty) -> Self {
112                Self(raw)
113            }
114
115/// Mirrors the `Metal` framework constant `fn`.
116            #[must_use]
117            pub const fn as_raw(self) -> $ty {
118                self.0
119            }
120        }
121    };
122}
123
124macro_rules! metal_string_constant {
125    ($(#[$meta:meta])* pub fn $name:ident => $symbol:literal;) => {
126        $(#[$meta])*
127/// Calls the `Metal` framework counterpart for this method.
128        #[must_use]
129        pub fn $name() -> Option<String> {
130            unsafe {
131                take_optional_string(
132                    ffi::ametal_copy_metal_string_constant(concat!($symbol, "\0").as_ptr().cast()),
133                )
134            }
135        }
136    };
137}
138
139/// Consume a heap-allocated array of retained device pointers produced by
140/// `ametal_copy_all_devices`, wrapping each into a [`MetalDevice`] and freeing
141/// the array allocation.
142///
143/// # Safety
144///
145/// * `ptr` must be either null or a valid pointer to `count` consecutive
146///   `*mut c_void` values, each holding a +1-retained `id<MTLDevice>`.
147/// * The array itself must have been allocated with `malloc` (it is freed
148///   with `libc::free` here).
149/// * `count` must equal the number of elements allocated at `ptr`.
150unsafe fn take_device_array(ptr: *mut *mut c_void, count: usize) -> Vec<MetalDevice> {
151    if ptr.is_null() || count == 0 {
152        return Vec::new();
153    }
154
155    let slice = core::slice::from_raw_parts(ptr, count);
156    let values = slice
157        .iter()
158        .copied()
159        .map(|device| unsafe { MetalDevice::from_raw(device) })
160        .collect();
161    libc::free(ptr.cast());
162    values
163}
164
165/// Mirrors the `Metal` framework counterpart for `MetalCommonCounter`.
166pub type MetalCommonCounter = String;
167/// Mirrors the `Metal` framework counterpart for `MetalCommonCounterSet`.
168pub type MetalCommonCounterSet = String;
169/// Mirrors the `Metal` framework counterpart for `MetalDeviceNotificationName`.
170pub type MetalDeviceNotificationName = String;
171/// Mirrors the `Metal` framework counterpart for `MetalAutoreleasedArgument`.
172pub type MetalAutoreleasedArgument = MetalArgument;
173/// Mirrors the `Metal` framework counterpart for `MetalArgumentType`.
174pub type MetalArgumentType = MetalBindingType;
175/// Mirrors the `Metal` framework counterpart for `MetalAutoreleasedComputePipelineReflection`.
176pub type MetalAutoreleasedComputePipelineReflection = MetalComputePipelineReflection;
177/// Mirrors the `Metal` framework counterpart for `MetalAutoreleasedRenderPipelineReflection`.
178pub type MetalAutoreleasedRenderPipelineReflection = MetalRenderPipelineReflection;
179/// Mirrors the `Metal` framework counterpart for `MetalNewLibraryCompletionHandler`.
180pub type MetalNewLibraryCompletionHandler =
181    Box<dyn FnMut(Result<MetalLibrary, String>) + Send + 'static>;
182/// Mirrors the `Metal` framework counterpart for `MetalNewDynamicLibraryCompletionHandler`.
183pub type MetalNewDynamicLibraryCompletionHandler =
184    Box<dyn FnMut(Result<DynamicLibrary, String>) + Send + 'static>;
185/// Mirrors the `Metal` framework counterpart for `MetalNewComputePipelineStateCompletionHandler`.
186pub type MetalNewComputePipelineStateCompletionHandler =
187    Box<dyn FnMut(Result<ComputePipelineState, String>) + Send + 'static>;
188/// Mirrors the `Metal` framework counterpart for `MetalNewComputePipelineStateWithReflectionCompletionHandler`.
189pub type MetalNewComputePipelineStateWithReflectionCompletionHandler = Box<
190    dyn FnMut(Result<(ComputePipelineState, MetalComputePipelineReflection), String>)
191        + Send
192        + 'static,
193>;
194/// Mirrors the `Metal` framework counterpart for `MetalNewRenderPipelineStateCompletionHandler`.
195pub type MetalNewRenderPipelineStateCompletionHandler =
196    Box<dyn FnMut(Result<RenderPipelineState, String>) + Send + 'static>;
197/// Mirrors the `Metal` framework counterpart for `MetalNewRenderPipelineStateWithReflectionCompletionHandler`.
198pub type MetalNewRenderPipelineStateWithReflectionCompletionHandler = Box<
199    dyn FnMut(Result<(RenderPipelineState, MetalRenderPipelineReflection), String>)
200        + Send
201        + 'static,
202>;
203/// Mirrors the `Metal` framework counterpart for `MetalTimestamp`.
204pub type MetalTimestamp = u64;
205
206/// Mirrors the `Metal` framework counterpart for `MetalCoordinate2D`.
207///
208/// # Examples
209///
210/// ```
211/// use apple_metal::MetalCoordinate2D;
212///
213/// let texel = MetalCoordinate2D::new(0.25, 0.75);
214/// assert_eq!(texel.x, 0.25);
215/// assert_eq!(texel.y, 0.75);
216/// ```
217#[derive(Debug, Clone, Copy, Default, PartialEq)]
218pub struct MetalCoordinate2D {
219    /// Mirrors the `Metal` framework property for `x`.
220    pub x: f32,
221    /// Mirrors the `Metal` framework property for `y`.
222    pub y: f32,
223}
224
225impl MetalCoordinate2D {
226    /// Mirrors the `Metal` framework constant `fn`.
227    #[must_use]
228    pub const fn new(x: f32, y: f32) -> Self {
229        Self { x, y }
230    }
231}
232
233/// Mirrors the `Metal` framework counterpart for `MetalSize`.
234///
235/// # Examples
236///
237/// ```
238/// use apple_metal::MetalSize;
239///
240/// let threads = MetalSize::new(8, 4, 1);
241/// assert_eq!(threads.width * threads.height, 32);
242/// assert_eq!(threads.depth, 1);
243/// ```
244#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
245pub struct MetalSize {
246    /// Mirrors the `Metal` framework property for `width`.
247    pub width: usize,
248    /// Mirrors the `Metal` framework property for `height`.
249    pub height: usize,
250    /// Mirrors the `Metal` framework property for `depth`.
251    pub depth: usize,
252}
253
254impl MetalSize {
255    /// Mirrors the `Metal` framework constant `fn`.
256    #[must_use]
257    pub const fn new(width: usize, height: usize, depth: usize) -> Self {
258        Self {
259            width,
260            height,
261            depth,
262        }
263    }
264}
265
266raw_value_type!(
267    /// Mirrors the `Metal` framework counterpart for `MetalGpuAddress`.
268    ///
269    /// # Examples
270    ///
271    /// ```
272    /// use apple_metal::MetalGpuAddress;
273    ///
274    /// let address = MetalGpuAddress::from_raw(0x1_0000);
275    /// assert_eq!(address.as_raw(), 0x1_0000);
276    /// ```
277    pub struct MetalGpuAddress(u64);
278);
279
280/// Mirrors the `Metal` framework counterpart for `MetalOrigin`.
281///
282/// # Examples
283///
284/// ```
285/// use apple_metal::MetalOrigin;
286///
287/// let origin = MetalOrigin::new(4, 2, 1);
288/// assert_eq!((origin.x, origin.y, origin.z), (4, 2, 1));
289/// ```
290#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
291pub struct MetalOrigin {
292    /// Mirrors the `Metal` framework property for `x`.
293    pub x: usize,
294    /// Mirrors the `Metal` framework property for `y`.
295    pub y: usize,
296    /// Mirrors the `Metal` framework property for `z`.
297    pub z: usize,
298}
299
300impl MetalOrigin {
301    /// Mirrors the `Metal` framework constant `fn`.
302    #[must_use]
303    pub const fn new(x: usize, y: usize, z: usize) -> Self {
304        Self { x, y, z }
305    }
306}
307
308/// Mirrors the `Metal` framework counterpart for `MetalRegion`.
309///
310/// # Examples
311///
312/// ```
313/// use apple_metal::MetalRegion;
314///
315/// let region = MetalRegion::new_2d(4, 8, 16, 32);
316/// assert_eq!(region.origin.x, 4);
317/// assert_eq!(region.size.height, 32);
318/// ```
319#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
320pub struct MetalRegion {
321    /// Mirrors the `Metal` framework property for `origin`.
322    pub origin: MetalOrigin,
323    /// Mirrors the `Metal` framework property for `size`.
324    pub size: MetalSize,
325}
326
327impl MetalRegion {
328    /// Mirrors the `Metal` framework constant `fn`.
329    #[must_use]
330    pub const fn new(origin: MetalOrigin, size: MetalSize) -> Self {
331        Self { origin, size }
332    }
333
334    /// Mirrors the `Metal` framework constant `fn`.
335    #[must_use]
336    pub const fn new_1d(x: usize, width: usize) -> Self {
337        Self {
338            origin: MetalOrigin::new(x, 0, 0),
339            size: MetalSize::new(width, 1, 1),
340        }
341    }
342
343    /// Mirrors the `Metal` framework constant `fn`.
344    #[must_use]
345    pub const fn new_2d(x: usize, y: usize, width: usize, height: usize) -> Self {
346        Self {
347            origin: MetalOrigin::new(x, y, 0),
348            size: MetalSize::new(width, height, 1),
349        }
350    }
351
352    /// Mirrors the `Metal` framework constant `fn`.
353    #[must_use]
354    pub const fn new_3d(
355        x: usize,
356        y: usize,
357        z: usize,
358        width: usize,
359        height: usize,
360        depth: usize,
361    ) -> Self {
362        Self {
363            origin: MetalOrigin::new(x, y, z),
364            size: MetalSize::new(width, height, depth),
365        }
366    }
367}
368
369/// Mirrors the `Metal` framework counterpart for `MetalResourceId`.
370///
371/// # Examples
372///
373/// ```
374/// use apple_metal::MetalResourceId;
375///
376/// let resource_id = MetalResourceId::new(42);
377/// assert_eq!(resource_id.value, 42);
378/// ```
379#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
380#[repr(transparent)]
381pub struct MetalResourceId {
382    /// Mirrors the `Metal` framework property for `value`.
383    pub value: u64,
384}
385
386impl MetalResourceId {
387    /// Mirrors the `Metal` framework constant `fn`.
388    #[must_use]
389    pub const fn new(value: u64) -> Self {
390        Self { value }
391    }
392}
393
394/// Mirrors the `Metal` framework counterpart for `MetalPackedFloat3`.
395///
396/// # Examples
397///
398/// ```
399/// use apple_metal::MetalPackedFloat3;
400///
401/// let normal = MetalPackedFloat3::new(0.0, 0.0, 1.0);
402/// assert_eq!(normal.z, 1.0);
403/// ```
404#[derive(Debug, Clone, Copy, Default, PartialEq)]
405pub struct MetalPackedFloat3 {
406    /// Mirrors the `Metal` framework property for `x`.
407    pub x: f32,
408    /// Mirrors the `Metal` framework property for `y`.
409    pub y: f32,
410    /// Mirrors the `Metal` framework property for `z`.
411    pub z: f32,
412}
413
414impl MetalPackedFloat3 {
415    /// Mirrors the `Metal` framework constant `fn`.
416    #[must_use]
417    pub const fn new(x: f32, y: f32, z: f32) -> Self {
418        Self { x, y, z }
419    }
420}
421
422/// Mirrors the `Metal` framework counterpart for `MetalPackedFloatQuaternion`.
423///
424/// # Examples
425///
426/// ```
427/// use apple_metal::MetalPackedFloatQuaternion;
428///
429/// let rotation = MetalPackedFloatQuaternion::default();
430/// assert_eq!(rotation, MetalPackedFloatQuaternion::new(0.0, 0.0, 0.0, 1.0));
431/// ```
432#[derive(Debug, Clone, Copy, PartialEq)]
433pub struct MetalPackedFloatQuaternion {
434    /// Mirrors the `Metal` framework property for `x`.
435    pub x: f32,
436    /// Mirrors the `Metal` framework property for `y`.
437    pub y: f32,
438    /// Mirrors the `Metal` framework property for `z`.
439    pub z: f32,
440    /// Mirrors the `Metal` framework property for `w`.
441    pub w: f32,
442}
443
444impl Default for MetalPackedFloatQuaternion {
445    fn default() -> Self {
446        Self {
447            x: 0.0,
448            y: 0.0,
449            z: 0.0,
450            w: 1.0,
451        }
452    }
453}
454
455impl MetalPackedFloatQuaternion {
456    /// Mirrors the `Metal` framework constant `fn`.
457    #[must_use]
458    pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
459        Self { x, y, z, w }
460    }
461}
462
463/// Mirrors the `Metal` framework counterpart for `MetalPackedFloat4x3`.
464///
465/// # Examples
466///
467/// ```
468/// use apple_metal::{MetalPackedFloat3, MetalPackedFloat4x3};
469///
470/// let basis = MetalPackedFloat4x3::new(
471///     MetalPackedFloat3::new(1.0, 0.0, 0.0),
472///     MetalPackedFloat3::new(0.0, 1.0, 0.0),
473///     MetalPackedFloat3::new(0.0, 0.0, 1.0),
474///     MetalPackedFloat3::new(4.0, 5.0, 6.0),
475/// );
476/// assert_eq!(basis.columns[3].y, 5.0);
477/// ```
478#[derive(Debug, Clone, Copy, Default, PartialEq)]
479pub struct MetalPackedFloat4x3 {
480    /// Mirrors the `Metal` framework property for `columns`.
481    pub columns: [MetalPackedFloat3; 4],
482}
483
484impl MetalPackedFloat4x3 {
485    /// Mirrors the `Metal` framework constant `fn`.
486    #[must_use]
487    pub const fn new(
488        column0: MetalPackedFloat3,
489        column1: MetalPackedFloat3,
490        column2: MetalPackedFloat3,
491        column3: MetalPackedFloat3,
492    ) -> Self {
493        Self {
494            columns: [column0, column1, column2, column3],
495        }
496    }
497}
498
499raw_value_type!(
500    /// Mirrors the `Metal` framework counterpart for `MetalSparseTextureMappingMode`.
501    pub struct MetalSparseTextureMappingMode(usize);
502);
503
504type DeviceObserverHandler = Mutex<Box<dyn FnMut(MetalDevice, &str) + Send>>;
505
506/// Mirrors the `Metal` framework counterpart for `MetalDeviceObserver`.
507pub struct MetalDeviceObserver {
508    ptr: *mut c_void,
509    removed: AtomicBool,
510    context: CallbackContext<DeviceObserverHandler>,
511}
512
513unsafe impl Send for MetalDeviceObserver {}
514unsafe impl Sync for MetalDeviceObserver {}
515
516impl Drop for MetalDeviceObserver {
517    fn drop(&mut self) {
518        self.remove();
519        unsafe { ffi::ametal_object_release(self.ptr) };
520    }
521}
522
523impl MetalDeviceObserver {
524    #[must_use]
525    pub const fn as_ptr(&self) -> *mut c_void {
526        self.ptr
527    }
528
529    /// Calls the `Metal` framework counterpart for `remove`.
530    pub fn remove(&self) {
531        if self.removed.swap(true, Ordering::AcqRel) {
532            return;
533        }
534        self.context.deactivate();
535        unsafe { ffi::ametal_remove_device_observer(self.ptr) };
536    }
537}
538
539unsafe extern "C" fn device_observer_trampoline(
540    device: *mut c_void,
541    notification_name: *const c_char,
542    context: *mut c_void,
543) {
544    let device = (!device.is_null()).then(|| unsafe { MetalDevice::from_raw(device) });
545    let notification_name = if notification_name.is_null() {
546        String::new()
547    } else {
548        unsafe { CStr::from_ptr(notification_name) }
549            .to_string_lossy()
550            .into_owned()
551    };
552    let _ = unsafe {
553        CallbackContext::<DeviceObserverHandler>::with(
554            context,
555            "MetalDeviceObserver",
556            move |handler| {
557                if let Some(device) = device {
558                    let mut handler = handler.lock().unwrap_or_else(PoisonError::into_inner);
559                    (*handler)(device, &notification_name);
560                }
561            },
562        )
563    };
564}
565
566impl MetalTensorDataType {
567    pub const FLOAT32: Self = Self(3);
568    pub const FLOAT16: Self = Self(16);
569    pub const BFLOAT16: Self = Self(121);
570    pub const INT8: Self = Self(45);
571    pub const UINT8: Self = Self(49);
572    pub const INT16: Self = Self(37);
573    pub const UINT16: Self = Self(41);
574    pub const INT32: Self = Self(29);
575    pub const UINT32: Self = Self(33);
576    pub const INT4: Self = Self(143);
577    pub const UINT4: Self = Self(144);
578
579    const fn bits(self) -> Option<usize> {
580        match self.0 {
581            3 | 29 | 33 => Some(32),
582            16 | 121 | 37 | 41 => Some(16),
583            45 | 49 => Some(8),
584            143 | 144 => Some(4),
585            _ => None,
586        }
587    }
588}
589
590impl MetalTensorUsage {
591    pub const COMPUTE: Self = Self(1);
592    pub const RENDER: Self = Self(1 << 1);
593    pub const MACHINE_LEARNING: Self = Self(1 << 2);
594}
595
596#[derive(Debug, Clone, PartialEq, Eq, Hash)]
597pub struct TensorDescriptor {
598    pub dimensions: Vec<usize>,
599    pub data_type: MetalTensorDataType,
600    pub usage: MetalTensorUsage,
601    pub storage_mode: usize,
602}
603
604impl TensorDescriptor {
605    #[must_use]
606    pub fn new(dimensions: &[usize], data_type: MetalTensorDataType) -> Self {
607        Self {
608            dimensions: dimensions.to_vec(),
609            data_type,
610            usage: MetalTensorUsage(MetalTensorUsage::COMPUTE.0 | MetalTensorUsage::RENDER.0),
611            storage_mode: crate::storage_mode::SHARED,
612        }
613    }
614}
615
616#[derive(Debug, Clone, PartialEq, Eq)]
617pub enum TensorError {
618    Unsupported,
619    InvalidRank { rank: usize },
620    UnsupportedDataType { data_type: usize },
621    InvalidUsage { usage: usize },
622    UnsupportedStorageMode { storage_mode: usize },
623    TooLarge { maximum_bytes: usize },
624    Native(String),
625}
626
627impl core::fmt::Display for TensorError {
628    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
629        match self {
630            Self::Unsupported => formatter.write_str("MTLTensor requires macOS 26.0 or later"),
631            Self::InvalidRank { rank } => {
632                write!(formatter, "tensor rank {rank} exceeds the maximum of 16")
633            }
634            Self::UnsupportedDataType { data_type } => {
635                write!(formatter, "tensor data type {data_type} is unknown")
636            }
637            Self::InvalidUsage { usage } => {
638                write!(formatter, "tensor usage {usage:#x} has unknown bits")
639            }
640            Self::UnsupportedStorageMode { storage_mode } => {
641                write!(
642                    formatter,
643                    "storage mode {storage_mode} cannot back a tensor"
644                )
645            }
646            Self::TooLarge { maximum_bytes } => write!(
647                formatter,
648                "the tensor needs more than the device's {maximum_bytes}-byte buffer limit"
649            ),
650            Self::Native(message) => formatter.write_str(message),
651        }
652    }
653}
654
655impl std::error::Error for TensorError {}
656
657impl MetalDevice {
658    #[must_use]
659    pub fn max_buffer_length(&self) -> usize {
660        unsafe { ffi::ametal_device_max_buffer_length(self.as_ptr()) }
661    }
662
663    #[allow(clippy::missing_errors_doc)]
664    pub fn new_tensor(&self, descriptor: &TensorDescriptor) -> Result<MetalTensor, TensorError> {
665        if !unsafe { ffi::ametal_tensors_supported() } {
666            return Err(TensorError::Unsupported);
667        }
668        let rank = descriptor.dimensions.len();
669        if rank > 16 {
670            return Err(TensorError::InvalidRank { rank });
671        }
672        let bits = descriptor
673            .data_type
674            .bits()
675            .ok_or(TensorError::UnsupportedDataType {
676                data_type: descriptor.data_type.0,
677            })?;
678        if descriptor.usage.0 & !0x7 != 0 {
679            return Err(TensorError::InvalidUsage {
680                usage: descriptor.usage.0,
681            });
682        }
683        if !matches!(
684            descriptor.storage_mode,
685            crate::storage_mode::SHARED
686                | crate::storage_mode::MANAGED
687                | crate::storage_mode::PRIVATE
688        ) {
689            return Err(TensorError::UnsupportedStorageMode {
690                storage_mode: descriptor.storage_mode,
691            });
692        }
693        let maximum_bytes = self.max_buffer_length();
694        let bytes = descriptor
695            .dimensions
696            .iter()
697            .try_fold(bits, |total, extent| {
698                isize::try_from(*extent).ok()?;
699                total.checked_mul(*extent)
700            })
701            .map(|total_bits| total_bits.div_ceil(8));
702        if bytes.is_none_or(|bytes| bytes > maximum_bytes) {
703            return Err(TensorError::TooLarge { maximum_bytes });
704        }
705        let mut err: *mut c_char = ptr::null_mut();
706        let tensor = unsafe {
707            ffi::ametal_device_new_tensor(
708                self.as_ptr(),
709                descriptor.dimensions.as_ptr(),
710                rank,
711                descriptor.data_type.0,
712                descriptor.usage.0,
713                descriptor.storage_mode,
714                &raw mut err,
715            )
716        };
717        MetalTensor::wrap(tensor).ok_or_else(|| {
718            TensorError::Native(
719                unsafe { take_optional_string(err) }.unwrap_or_else(|| {
720                    "MTLDevice.makeTensor(descriptor:) returned nil".to_string()
721                }),
722            )
723        })
724    }
725}
726
727/// Calls the `Metal` framework counterpart for `copy_all_devices`.
728#[must_use]
729pub fn copy_all_devices() -> Vec<MetalDevice> {
730    let mut count = 0;
731    let ptr = unsafe { ffi::ametal_copy_all_devices(&raw mut count) };
732    unsafe { take_device_array(ptr, count) }
733}
734
735/// Enumerate all Metal devices while registering a hot-plug/removal observer.
736#[must_use]
737pub fn copy_all_devices_with_observer<F>(
738    handler: F,
739) -> (Vec<MetalDevice>, Option<MetalDeviceObserver>)
740where
741    F: FnMut(MetalDevice, &str) + Send + 'static,
742{
743    let context: CallbackContext<DeviceObserverHandler> =
744        CallbackContext::new(Mutex::new(Box::new(handler)));
745    let mut count = 0;
746    let mut observer = ptr::null_mut();
747    let devices = unsafe {
748        ffi::ametal_copy_all_devices_with_observer(
749            &raw mut count,
750            &raw mut observer,
751            Some(device_observer_trampoline),
752            context.retained_ptr(),
753            Some(CallbackContext::<DeviceObserverHandler>::RELEASE),
754        )
755    };
756    let devices = unsafe { take_device_array(devices, count) };
757    let observer = (!observer.is_null()).then(|| MetalDeviceObserver {
758        ptr: observer,
759        removed: AtomicBool::new(false),
760        context,
761    });
762    (devices, observer)
763}
764
765/// Calls the `Metal` framework counterpart for `remove_device_observer`.
766pub fn remove_device_observer(observer: &MetalDeviceObserver) {
767    observer.remove();
768}
769
770/// Mirrors the `Metal` framework counterpart for `MetalIoCompressionContext`.
771pub struct MetalIoCompressionContext {
772    ptr: *mut c_void,
773}
774
775impl Drop for MetalIoCompressionContext {
776    fn drop(&mut self) {
777        if !self.ptr.is_null() {
778            unsafe { ffi::ametal_io_flush_and_destroy_compression_context(self.ptr) };
779            self.ptr = ptr::null_mut();
780        }
781    }
782}
783
784impl MetalIoCompressionContext {
785    /// Mirrors the `Metal` framework constant `fn`.
786    #[must_use]
787    pub const fn as_ptr(&self) -> *mut c_void {
788        self.ptr
789    }
790
791    /// Wrap a raw `MTLIOCompressionContext` pointer returned by the Swift bridge.
792    ///
793    /// # Safety
794    ///
795    /// `ptr` must be a valid, non-null `MTLIOCompressionContext *` whose
796    /// ownership is transferred to this value.  The context will be flushed
797    /// and destroyed when this value is dropped or `flush_and_destroy` is
798    /// called.  Do not use `ptr` after calling this function.
799    #[must_use]
800    pub unsafe fn from_raw(ptr: *mut c_void) -> Self {
801        Self { ptr }
802    }
803
804    /// Calls the `Metal` framework counterpart for `append_data`.
805    pub fn append_data(&self, data: &[u8]) {
806        unsafe {
807            ffi::ametal_io_compression_context_append_data(self.ptr, data.as_ptr(), data.len());
808        }
809    }
810
811    /// Calls the `Metal` framework counterpart for `flush_and_destroy`.
812    #[must_use]
813    pub fn flush_and_destroy(mut self) -> MetalIoCompressionStatus {
814        let status = unsafe { ffi::ametal_io_flush_and_destroy_compression_context(self.ptr) };
815        self.ptr = ptr::null_mut();
816        MetalIoCompressionStatus::from_raw(status)
817    }
818}
819
820/// Calls the `Metal` framework counterpart for `io_compression_context_default_chunk_size`.
821#[must_use]
822pub fn io_compression_context_default_chunk_size() -> usize {
823    unsafe { ffi::ametal_io_compression_context_default_chunk_size() }
824}
825
826/// Calls the `Metal` framework counterpart for `create_io_compression_context`.
827#[must_use]
828pub fn create_io_compression_context(
829    path: &Path,
830    method: MetalIoCompressionMethod,
831    chunk_size: Option<usize>,
832) -> Option<MetalIoCompressionContext> {
833    let path = c_string(path.to_string_lossy().as_ref()).ok()?;
834    let chunk_size = chunk_size.unwrap_or_else(io_compression_context_default_chunk_size);
835    let ptr = unsafe {
836        ffi::ametal_io_create_compression_context(path.as_ptr(), method.as_raw(), chunk_size)
837    };
838    if ptr.is_null() {
839        None
840    } else {
841        Some(unsafe { MetalIoCompressionContext::from_raw(ptr) })
842    }
843}
844
845metal_string_constant!(pub fn metal4_command_queue_error_domain => "MTL4CommandQueueErrorDomain";);
846metal_string_constant!(pub fn metal_binary_archive_domain => "MTLBinaryArchiveDomain";);
847metal_string_constant!(pub fn metal_capture_error_domain => "MTLCaptureErrorDomain";);
848metal_string_constant!(pub fn metal_command_buffer_encoder_info_error_key => "MTLCommandBufferEncoderInfoErrorKey";);
849metal_string_constant!(pub fn metal_command_buffer_error_domain => "MTLCommandBufferErrorDomain";);
850metal_string_constant!(pub fn metal_common_counter_clipper_invocations => "MTLCommonCounterClipperInvocations";);
851metal_string_constant!(pub fn metal_common_counter_clipper_primitives_out => "MTLCommonCounterClipperPrimitivesOut";);
852metal_string_constant!(pub fn metal_common_counter_compute_kernel_invocations => "MTLCommonCounterComputeKernelInvocations";);
853metal_string_constant!(pub fn metal_common_counter_fragment_cycles => "MTLCommonCounterFragmentCycles";);
854metal_string_constant!(pub fn metal_common_counter_fragment_invocations => "MTLCommonCounterFragmentInvocations";);
855metal_string_constant!(pub fn metal_common_counter_fragments_passed => "MTLCommonCounterFragmentsPassed";);
856metal_string_constant!(pub fn metal_common_counter_post_tessellation_vertex_cycles => "MTLCommonCounterPostTessellationVertexCycles";);
857metal_string_constant!(pub fn metal_common_counter_post_tessellation_vertex_invocations => "MTLCommonCounterPostTessellationVertexInvocations";);
858metal_string_constant!(pub fn metal_common_counter_render_target_write_cycles => "MTLCommonCounterRenderTargetWriteCycles";);
859metal_string_constant!(pub fn metal_common_counter_set_stage_utilization => "MTLCommonCounterSetStageUtilization";);
860metal_string_constant!(pub fn metal_common_counter_set_statistic => "MTLCommonCounterSetStatistic";);
861metal_string_constant!(pub fn metal_common_counter_set_timestamp => "MTLCommonCounterSetTimestamp";);
862metal_string_constant!(pub fn metal_common_counter_tessellation_cycles => "MTLCommonCounterTessellationCycles";);
863metal_string_constant!(pub fn metal_common_counter_tessellation_input_patches => "MTLCommonCounterTessellationInputPatches";);
864metal_string_constant!(pub fn metal_common_counter_timestamp => "MTLCommonCounterTimestamp";);
865metal_string_constant!(pub fn metal_common_counter_total_cycles => "MTLCommonCounterTotalCycles";);
866metal_string_constant!(pub fn metal_common_counter_vertex_cycles => "MTLCommonCounterVertexCycles";);
867metal_string_constant!(pub fn metal_common_counter_vertex_invocations => "MTLCommonCounterVertexInvocations";);
868metal_string_constant!(pub fn metal_counter_error_domain => "MTLCounterErrorDomain";);
869metal_string_constant!(pub fn metal_device_removal_requested_notification => "MTLDeviceRemovalRequestedNotification";);
870metal_string_constant!(pub fn metal_device_was_added_notification => "MTLDeviceWasAddedNotification";);
871metal_string_constant!(pub fn metal_device_was_removed_notification => "MTLDeviceWasRemovedNotification";);
872metal_string_constant!(pub fn metal_dynamic_library_domain => "MTLDynamicLibraryDomain";);
873metal_string_constant!(pub fn metal_io_error_domain => "MTLIOErrorDomain";);
874metal_string_constant!(pub fn metal_library_error_domain => "MTLLibraryErrorDomain";);
875metal_string_constant!(pub fn metal_log_state_error_domain => "MTLLogStateErrorDomain";);
876metal_string_constant!(pub fn metal_tensor_domain => "MTLTensorDomain";);
877
878raw_value_type!(
879    /// Mirrors the `Metal` framework counterpart for `Metal4AlphaToCoverageState`.
880    pub struct Metal4AlphaToCoverageState(usize);
881);
882raw_value_type!(
883    /// Mirrors the `Metal` framework counterpart for `Metal4AlphaToOneState`.
884    pub struct Metal4AlphaToOneState(usize);
885);
886raw_value_type!(
887    /// Mirrors the `Metal` framework counterpart for `Metal4BinaryFunctionOptions`.
888    pub struct Metal4BinaryFunctionOptions(usize);
889);
890raw_value_type!(
891    /// Mirrors the `Metal` framework counterpart for `Metal4BlendState`.
892    pub struct Metal4BlendState(usize);
893);
894raw_value_type!(
895    /// Mirrors the `Metal` framework counterpart for `Metal4CommandQueueError`.
896    pub struct Metal4CommandQueueError(usize);
897);
898raw_value_type!(
899    /// Mirrors the `Metal` framework counterpart for `Metal4CompilerTaskStatus`.
900    pub struct Metal4CompilerTaskStatus(usize);
901);
902raw_value_type!(
903    /// Mirrors the `Metal` framework counterpart for `Metal4CounterHeapType`.
904    pub struct Metal4CounterHeapType(usize);
905);
906raw_value_type!(
907    /// Mirrors the `Metal` framework counterpart for `Metal4IndirectCommandBufferSupportState`.
908    pub struct Metal4IndirectCommandBufferSupportState(usize);
909);
910raw_value_type!(
911    /// Mirrors the `Metal` framework counterpart for `Metal4LogicalToPhysicalColorAttachmentMappingState`.
912    pub struct Metal4LogicalToPhysicalColorAttachmentMappingState(usize);
913);
914raw_value_type!(
915    /// Mirrors the `Metal` framework counterpart for `Metal4PipelineDataSetSerializerConfiguration`.
916    pub struct Metal4PipelineDataSetSerializerConfiguration(usize);
917);
918raw_value_type!(
919    /// Mirrors the `Metal` framework counterpart for `Metal4RenderEncoderOptions`.
920    pub struct Metal4RenderEncoderOptions(usize);
921);
922raw_value_type!(
923    /// Mirrors the `Metal` framework counterpart for `Metal4ShaderReflection`.
924    pub struct Metal4ShaderReflection(usize);
925);
926raw_value_type!(
927    /// Mirrors the `Metal` framework counterpart for `Metal4TimestampGranularity`.
928    pub struct Metal4TimestampGranularity(usize);
929);
930raw_value_type!(
931    /// Mirrors the `Metal` framework counterpart for `Metal4VisibilityOptions`.
932    pub struct Metal4VisibilityOptions(usize);
933);
934raw_value_type!(
935    /// Mirrors the `Metal` framework counterpart for `MetalAccelerationStructureInstanceDescriptorType`.
936    pub struct MetalAccelerationStructureInstanceDescriptorType(usize);
937);
938raw_value_type!(
939    /// Mirrors the `Metal` framework counterpart for `MetalAccelerationStructureInstanceOptions`.
940    pub struct MetalAccelerationStructureInstanceOptions(usize);
941);
942raw_value_type!(
943    /// Mirrors the `Metal` framework counterpart for `MetalAccelerationStructureRefitOptions`.
944    pub struct MetalAccelerationStructureRefitOptions(usize);
945);
946raw_value_type!(
947    /// Mirrors the `Metal` framework counterpart for `MetalAccelerationStructureUsage`.
948    pub struct MetalAccelerationStructureUsage(usize);
949);
950raw_value_type!(
951    /// Mirrors the `Metal` framework counterpart for `MetalArgumentAccess`.
952    pub struct MetalArgumentAccess(usize);
953);
954raw_value_type!(
955    /// Mirrors the `Metal` framework counterpart for `MetalAttributeFormat`.
956    pub struct MetalAttributeFormat(usize);
957);
958raw_value_type!(
959    /// Mirrors the `Metal` framework counterpart for `MetalBarrierScope`.
960    pub struct MetalBarrierScope(usize);
961);
962raw_value_type!(
963    /// Mirrors the `Metal` framework counterpart for `MetalBinaryArchiveError`.
964    pub struct MetalBinaryArchiveError(usize);
965);
966raw_value_type!(
967    /// Mirrors the `Metal` framework counterpart for `MetalBindingType`.
968    pub struct MetalBindingType(usize);
969);
970raw_value_type!(
971    /// Mirrors the `Metal` framework counterpart for `MetalBlitOption`.
972    pub struct MetalBlitOption(usize);
973);
974raw_value_type!(
975    /// Mirrors the `Metal` framework counterpart for `MetalBufferSparseTier`.
976    pub struct MetalBufferSparseTier(usize);
977);
978raw_value_type!(
979    /// Mirrors the `Metal` framework counterpart for `MetalCaptureError`.
980    pub struct MetalCaptureError(usize);
981);
982raw_value_type!(
983    /// Mirrors the `Metal` framework counterpart for `MetalCommandBufferError`.
984    pub struct MetalCommandBufferError(usize);
985);
986raw_value_type!(
987    /// Mirrors the `Metal` framework counterpart for `MetalCommandBufferErrorOption`.
988    pub struct MetalCommandBufferErrorOption(usize);
989);
990raw_value_type!(
991    /// Mirrors the `Metal` framework counterpart for `MetalCommandEncoderErrorState`.
992    pub struct MetalCommandEncoderErrorState(usize);
993);
994raw_value_type!(
995    /// Mirrors the `Metal` framework counterpart for `MetalCompileSymbolVisibility`.
996    pub struct MetalCompileSymbolVisibility(usize);
997);
998raw_value_type!(
999    /// Mirrors the `Metal` framework counterpart for `MetalCounterSampleBufferError`.
1000    pub struct MetalCounterSampleBufferError(usize);
1001);
1002raw_value_type!(
1003    /// Mirrors the `Metal` framework counterpart for `MetalCullMode`.
1004    pub struct MetalCullMode(usize);
1005);
1006raw_value_type!(
1007    /// Mirrors the `Metal` framework counterpart for `MetalCurveBasis`.
1008    pub struct MetalCurveBasis(usize);
1009);
1010raw_value_type!(
1011    /// Mirrors the `Metal` framework counterpart for `MetalCurveEndCaps`.
1012    pub struct MetalCurveEndCaps(usize);
1013);
1014raw_value_type!(
1015    /// Mirrors the `Metal` framework counterpart for `MetalCurveType`.
1016    pub struct MetalCurveType(usize);
1017);
1018raw_value_type!(
1019    /// Mirrors the `Metal` framework counterpart for `MetalDataType`.
1020    pub struct MetalDataType(usize);
1021);
1022raw_value_type!(
1023    /// Mirrors the `Metal` framework counterpart for `MetalDepthClipMode`.
1024    pub struct MetalDepthClipMode(usize);
1025);
1026raw_value_type!(
1027    /// Mirrors the `Metal` framework counterpart for `MetalDeviceLocation`.
1028    pub struct MetalDeviceLocation(usize);
1029);
1030raw_value_type!(
1031    /// Mirrors the `Metal` framework counterpart for `MetalDispatchType`.
1032    pub struct MetalDispatchType(usize);
1033);
1034raw_value_type!(
1035    /// Mirrors the `Metal` framework counterpart for `MetalDynamicLibraryError`.
1036    pub struct MetalDynamicLibraryError(usize);
1037);
1038raw_value_type!(
1039    /// Mirrors the `Metal` framework counterpart for `MetalFeatureSet`.
1040    pub struct MetalFeatureSet(usize);
1041);
1042raw_value_type!(
1043    /// Mirrors the `Metal` framework counterpart for `MetalFunctionLogType`.
1044    pub struct MetalFunctionLogType(usize);
1045);
1046raw_value_type!(
1047    /// Mirrors the `Metal` framework counterpart for `MetalFunctionOptions`.
1048    pub struct MetalFunctionOptions(usize);
1049);
1050raw_value_type!(
1051    /// Mirrors the `Metal` framework counterpart for `MetalFunctionType`.
1052    pub struct MetalFunctionType(usize);
1053);
1054raw_value_type!(
1055    /// Mirrors the `Metal` framework counterpart for `MetalHeapType`.
1056    pub struct MetalHeapType(usize);
1057);
1058raw_value_type!(
1059    /// Mirrors the `Metal` framework counterpart for `MetalIndexType`.
1060    pub struct MetalIndexType(usize);
1061);
1062raw_value_type!(
1063    /// Mirrors the `Metal` framework counterpart for `MetalIoCommandQueueType`.
1064    pub struct MetalIoCommandQueueType(usize);
1065);
1066raw_value_type!(
1067    /// Mirrors the `Metal` framework counterpart for `MetalIoCompressionMethod`.
1068    pub struct MetalIoCompressionMethod(usize);
1069);
1070raw_value_type!(
1071    /// Mirrors the `Metal` framework counterpart for `MetalIoCompressionStatus`.
1072    pub struct MetalIoCompressionStatus(usize);
1073);
1074raw_value_type!(
1075    /// Mirrors the `Metal` framework counterpart for `MetalIoPriority`.
1076    pub struct MetalIoPriority(usize);
1077);
1078raw_value_type!(
1079    /// Mirrors the `Metal` framework counterpart for `MetalIoStatus`.
1080    pub struct MetalIoStatus(usize);
1081);
1082raw_value_type!(
1083    /// Mirrors the `Metal` framework counterpart for `MetalLanguageVersion`.
1084    pub struct MetalLanguageVersion(usize);
1085);
1086raw_value_type!(
1087    /// Mirrors the `Metal` framework counterpart for `MetalLibraryError`.
1088    pub struct MetalLibraryError(usize);
1089);
1090raw_value_type!(
1091    /// Mirrors the `Metal` framework counterpart for `MetalLibraryOptimizationLevel`.
1092    pub struct MetalLibraryOptimizationLevel(usize);
1093);
1094raw_value_type!(
1095    /// Mirrors the `Metal` framework counterpart for `MetalLibraryType`.
1096    pub struct MetalLibraryType(usize);
1097);
1098raw_value_type!(
1099    /// Mirrors the `Metal` framework counterpart for `MetalLogStateError`.
1100    pub struct MetalLogStateError(usize);
1101);
1102raw_value_type!(
1103    /// Mirrors the `Metal` framework counterpart for `MetalMathFloatingPointFunctions`.
1104    pub struct MetalMathFloatingPointFunctions(usize);
1105);
1106raw_value_type!(
1107    /// Mirrors the `Metal` framework counterpart for `MetalMathMode`.
1108    pub struct MetalMathMode(usize);
1109);
1110raw_value_type!(
1111    /// Mirrors the `Metal` framework counterpart for `MetalMatrixLayout`.
1112    pub struct MetalMatrixLayout(usize);
1113);
1114raw_value_type!(
1115    /// Mirrors the `Metal` framework counterpart for `MetalMotionBorderMode`.
1116    pub struct MetalMotionBorderMode(usize);
1117);
1118raw_value_type!(
1119    /// Mirrors the `Metal` framework counterpart for `MetalMultisampleDepthResolveFilter`.
1120    pub struct MetalMultisampleDepthResolveFilter(usize);
1121);
1122raw_value_type!(
1123    /// Mirrors the `Metal` framework counterpart for `MetalMultisampleStencilResolveFilter`.
1124    pub struct MetalMultisampleStencilResolveFilter(usize);
1125);
1126raw_value_type!(
1127    /// Mirrors the `Metal` framework counterpart for `MetalMutability`.
1128    pub struct MetalMutability(usize);
1129);
1130raw_value_type!(
1131    /// Mirrors the `Metal` framework counterpart for `MetalPatchType`.
1132    pub struct MetalPatchType(usize);
1133);
1134raw_value_type!(
1135    /// Mirrors the `Metal` framework counterpart for `MetalPipelineOption`.
1136    pub struct MetalPipelineOption(usize);
1137);
1138raw_value_type!(
1139    /// Mirrors the `Metal` framework counterpart for `MetalPrimitiveTopologyClass`.
1140    pub struct MetalPrimitiveTopologyClass(usize);
1141);
1142raw_value_type!(
1143    /// Mirrors the `Metal` framework counterpart for `MetalReadWriteTextureTier`.
1144    pub struct MetalReadWriteTextureTier(usize);
1145);
1146raw_value_type!(
1147    /// Mirrors the `Metal` framework counterpart for `MetalRenderStages`.
1148    pub struct MetalRenderStages(usize);
1149);
1150raw_value_type!(
1151    /// Mirrors the `Metal` framework counterpart for `MetalResourceUsage`.
1152    pub struct MetalResourceUsage(usize);
1153);
1154raw_value_type!(
1155    /// Mirrors the `Metal` framework counterpart for `MetalShaderValidation`.
1156    pub struct MetalShaderValidation(usize);
1157);
1158raw_value_type!(
1159    /// Mirrors the `Metal` framework counterpart for `MetalSparsePageSize`.
1160    pub struct MetalSparsePageSize(usize);
1161);
1162raw_value_type!(
1163    /// Mirrors the `Metal` framework counterpart for `MetalSparseTextureRegionAlignmentMode`.
1164    pub struct MetalSparseTextureRegionAlignmentMode(usize);
1165);
1166raw_value_type!(
1167    /// Mirrors the `Metal` framework counterpart for `MetalStages`.
1168    pub struct MetalStages(usize);
1169);
1170raw_value_type!(
1171    /// Mirrors the `Metal` framework counterpart for `MetalStepFunction`.
1172    pub struct MetalStepFunction(usize);
1173);
1174raw_value_type!(
1175    /// Mirrors the `Metal` framework counterpart for `MetalStitchedLibraryOptions`.
1176    pub struct MetalStitchedLibraryOptions(usize);
1177);
1178raw_value_type!(
1179    /// Mirrors the `Metal` framework counterpart for `MetalStoreActionOptions`.
1180    pub struct MetalStoreActionOptions(usize);
1181);
1182raw_value_type!(
1183    /// Mirrors the `Metal` framework counterpart for `MetalTensorDataType`.
1184    pub struct MetalTensorDataType(usize);
1185);
1186raw_value_type!(
1187    /// Mirrors the `Metal` framework counterpart for `MetalTensorError`.
1188    pub struct MetalTensorError(usize);
1189);
1190raw_value_type!(
1191    /// Mirrors the `Metal` framework counterpart for `MetalTensorUsage`.
1192    pub struct MetalTensorUsage(usize);
1193);
1194raw_value_type!(
1195    /// Mirrors the `Metal` framework counterpart for `MetalTessellationControlPointIndexType`.
1196    pub struct MetalTessellationControlPointIndexType(usize);
1197);
1198raw_value_type!(
1199    /// Mirrors the `Metal` framework counterpart for `MetalTessellationFactorFormat`.
1200    pub struct MetalTessellationFactorFormat(usize);
1201);
1202raw_value_type!(
1203    /// Mirrors the `Metal` framework counterpart for `MetalTessellationFactorStepFunction`.
1204    pub struct MetalTessellationFactorStepFunction(usize);
1205);
1206raw_value_type!(
1207    /// Mirrors the `Metal` framework counterpart for `MetalTessellationPartitionMode`.
1208    pub struct MetalTessellationPartitionMode(usize);
1209);
1210raw_value_type!(
1211    /// Mirrors the `Metal` framework counterpart for `MetalTextureCompressionType`.
1212    pub struct MetalTextureCompressionType(usize);
1213);
1214raw_value_type!(
1215    /// Mirrors the `Metal` framework counterpart for `MetalTextureSparseTier`.
1216    pub struct MetalTextureSparseTier(usize);
1217);
1218raw_value_type!(
1219    /// Mirrors the `Metal` framework counterpart for `MetalTextureSwizzle`.
1220    pub struct MetalTextureSwizzle(usize);
1221);
1222raw_value_type!(
1223    /// Mirrors the `Metal` framework counterpart for `MetalTransformType`.
1224    pub struct MetalTransformType(usize);
1225);
1226raw_value_type!(
1227    /// Mirrors the `Metal` framework counterpart for `MetalTriangleFillMode`.
1228    pub struct MetalTriangleFillMode(usize);
1229);
1230raw_value_type!(
1231    /// Mirrors the `Metal` framework counterpart for `MetalVertexFormat`.
1232    pub struct MetalVertexFormat(usize);
1233);
1234raw_value_type!(
1235    /// Mirrors the `Metal` framework counterpart for `MetalVertexStepFunction`.
1236    pub struct MetalVertexStepFunction(usize);
1237);
1238raw_value_type!(
1239    /// Mirrors the `Metal` framework counterpart for `MetalVisibilityResultMode`.
1240    pub struct MetalVisibilityResultMode(usize);
1241);
1242raw_value_type!(
1243    /// Mirrors the `Metal` framework counterpart for `MetalVisibilityResultType`.
1244    pub struct MetalVisibilityResultType(usize);
1245);
1246raw_value_type!(
1247    /// Mirrors the `Metal` framework counterpart for `MetalWinding`.
1248    pub struct MetalWinding(usize);
1249);
1250opaque_symbol_handle!(
1251    /// Mirrors the `Metal` framework counterpart for `Metal4Archive`.
1252    pub struct Metal4Archive;
1253);
1254opaque_symbol_handle!(
1255    /// Mirrors the `Metal` framework counterpart for `Metal4ArgumentTable`.
1256    pub struct Metal4ArgumentTable;
1257);
1258opaque_symbol_handle!(
1259    /// Mirrors the `Metal` framework counterpart for `Metal4BinaryFunction`.
1260    pub struct Metal4BinaryFunction;
1261);
1262opaque_symbol_handle!(
1263    /// Mirrors the `Metal` framework counterpart for `Metal4CommandAllocator`.
1264    pub struct Metal4CommandAllocator;
1265);
1266opaque_symbol_handle!(
1267    /// Mirrors the `Metal` framework counterpart for `Metal4CommandBuffer`.
1268    pub struct Metal4CommandBuffer;
1269);
1270opaque_symbol_handle!(
1271    /// Mirrors the `Metal` framework counterpart for `Metal4CommandEncoder`.
1272    pub struct Metal4CommandEncoder;
1273);
1274opaque_symbol_handle!(
1275    /// Mirrors the `Metal` framework counterpart for `Metal4CommandQueue`.
1276    pub struct Metal4CommandQueue;
1277);
1278opaque_symbol_handle!(
1279    /// Mirrors the `Metal` framework counterpart for `Metal4CommitFeedback`.
1280    pub struct Metal4CommitFeedback;
1281);
1282opaque_symbol_handle!(
1283    /// Mirrors the `Metal` framework counterpart for `Metal4Compiler`.
1284    pub struct Metal4Compiler;
1285);
1286opaque_symbol_handle!(
1287    /// Mirrors the `Metal` framework counterpart for `Metal4CompilerTask`.
1288    pub struct Metal4CompilerTask;
1289);
1290opaque_symbol_handle!(
1291    /// Mirrors the `Metal` framework counterpart for `Metal4ComputeCommandEncoder`.
1292    pub struct Metal4ComputeCommandEncoder;
1293);
1294opaque_symbol_handle!(
1295    /// Mirrors the `Metal` framework counterpart for `Metal4CounterHeap`.
1296    pub struct Metal4CounterHeap;
1297);
1298opaque_symbol_handle!(
1299    /// Mirrors the `Metal` framework counterpart for `Metal4FxFrameInterpolator`.
1300    pub struct Metal4FxFrameInterpolator;
1301);
1302opaque_symbol_handle!(
1303    /// Mirrors the `Metal` framework counterpart for `Metal4FxSpatialScaler`.
1304    pub struct Metal4FxSpatialScaler;
1305);
1306opaque_symbol_handle!(
1307    /// Mirrors the `Metal` framework counterpart for `Metal4FxTemporalDenoisedScaler`.
1308    pub struct Metal4FxTemporalDenoisedScaler;
1309);
1310opaque_symbol_handle!(
1311    /// Mirrors the `Metal` framework counterpart for `Metal4FxTemporalScaler`.
1312    pub struct Metal4FxTemporalScaler;
1313);
1314opaque_symbol_handle!(
1315    /// Mirrors the `Metal` framework counterpart for `Metal4MachineLearningCommandEncoder`.
1316    pub struct Metal4MachineLearningCommandEncoder;
1317);
1318opaque_symbol_handle!(
1319    /// Mirrors the `Metal` framework counterpart for `Metal4MachineLearningPipelineState`.
1320    pub struct Metal4MachineLearningPipelineState;
1321);
1322opaque_symbol_handle!(
1323    /// Mirrors the `Metal` framework counterpart for `Metal4PipelineDataSetSerializer`.
1324    pub struct Metal4PipelineDataSetSerializer;
1325);
1326opaque_symbol_handle!(
1327    /// Mirrors the `Metal` framework counterpart for `Metal4RenderCommandEncoder`.
1328    pub struct Metal4RenderCommandEncoder;
1329);
1330opaque_symbol_handle!(
1331    /// Mirrors the `Metal` framework counterpart for `MetalAccelerationStructureCommandEncoder`.
1332    pub struct MetalAccelerationStructureCommandEncoder;
1333);
1334opaque_symbol_handle!(
1335    /// Mirrors the `Metal` framework counterpart for `MetalAllocation`.
1336    pub struct MetalAllocation;
1337);
1338opaque_symbol_handle!(
1339    /// Mirrors the `Metal` framework counterpart for `MetalBinding`.
1340    pub struct MetalBinding;
1341);
1342opaque_symbol_handle!(
1343    /// Mirrors the `Metal` framework counterpart for `MetalBufferBinding`.
1344    pub struct MetalBufferBinding;
1345);
1346opaque_symbol_handle!(
1347    /// Mirrors the `Metal` framework counterpart for `MetalCommandBufferEncoderInfo`.
1348    pub struct MetalCommandBufferEncoderInfo;
1349);
1350opaque_symbol_handle!(
1351    /// Mirrors the `Metal` framework counterpart for `MetalCommandEncoder`.
1352    pub struct MetalCommandEncoder;
1353);
1354opaque_symbol_handle!(
1355    /// Mirrors the `Metal` framework counterpart for `MetalCounter`.
1356    pub struct MetalCounter;
1357);
1358opaque_symbol_handle!(
1359    /// Mirrors the `Metal` framework counterpart for `MetalDrawable`.
1360    pub struct MetalDrawable;
1361);
1362opaque_symbol_handle!(
1363    /// Mirrors the `Metal` framework counterpart for `MetalFunctionHandle`.
1364    pub struct MetalFunctionHandle;
1365);
1366opaque_symbol_handle!(
1367    /// Mirrors the `Metal` framework counterpart for `MetalFunctionLog`.
1368    pub struct MetalFunctionLog;
1369);
1370opaque_symbol_handle!(
1371    /// Mirrors the `Metal` framework counterpart for `MetalFunctionLogDebugLocation`.
1372    pub struct MetalFunctionLogDebugLocation;
1373);
1374opaque_symbol_handle!(
1375    /// Mirrors the `Metal` framework counterpart for `MetalFunctionStitchingAttribute`.
1376    pub struct MetalFunctionStitchingAttribute;
1377);
1378opaque_symbol_handle!(
1379    /// Mirrors the `Metal` framework counterpart for `MetalFunctionStitchingNode`.
1380    pub struct MetalFunctionStitchingNode;
1381);
1382opaque_symbol_handle!(
1383    /// Mirrors the `Metal` framework counterpart for `MetalFxFrameInterpolator`.
1384    pub struct MetalFxFrameInterpolator;
1385);
1386opaque_symbol_handle!(
1387    /// Mirrors the `Metal` framework counterpart for `MetalFxFrameInterpolatorBase`.
1388    pub struct MetalFxFrameInterpolatorBase;
1389);
1390opaque_symbol_handle!(
1391    /// Mirrors the `Metal` framework counterpart for `MetalFxSpatialScalerBase`.
1392    pub struct MetalFxSpatialScalerBase;
1393);
1394opaque_symbol_handle!(
1395    /// Mirrors the `Metal` framework counterpart for `MetalFxTemporalDenoisedScaler`.
1396    pub struct MetalFxTemporalDenoisedScaler;
1397);
1398opaque_symbol_handle!(
1399    /// Mirrors the `Metal` framework counterpart for `MetalFxTemporalDenoisedScalerBase`.
1400    pub struct MetalFxTemporalDenoisedScalerBase;
1401);
1402opaque_symbol_handle!(
1403    /// Mirrors the `Metal` framework counterpart for `MetalFxTemporalScalerBase`.
1404    pub struct MetalFxTemporalScalerBase;
1405);
1406opaque_symbol_handle!(
1407    /// Mirrors the `Metal` framework counterpart for `MetalIndirectComputeCommand`.
1408    pub struct MetalIndirectComputeCommand;
1409);
1410opaque_symbol_handle!(
1411    /// `id<MTLIndirectComputeCommandEncoder>` — encodes indirect compute dispatches.
1412    pub struct MetalIndirectComputeCommandEncoder;
1413);
1414opaque_symbol_handle!(
1415    /// Mirrors the `Metal` framework counterpart for `MetalIndirectRenderCommand`.
1416    pub struct MetalIndirectRenderCommand;
1417);
1418opaque_symbol_handle!(
1419    /// `id<MTLIndirectRenderCommandEncoder>` — encodes indirect render commands.
1420    pub struct MetalIndirectRenderCommandEncoder;
1421);
1422opaque_symbol_handle!(
1423    /// Mirrors the `Metal` framework counterpart for `MetalIoCommandBuffer`.
1424    pub struct MetalIoCommandBuffer;
1425);
1426opaque_symbol_handle!(
1427    /// Mirrors the `Metal` framework counterpart for `MetalIoCommandQueue`.
1428    pub struct MetalIoCommandQueue;
1429);
1430opaque_symbol_handle!(
1431    /// Mirrors the `Metal` framework counterpart for `MetalIoFileHandle`.
1432    pub struct MetalIoFileHandle;
1433);
1434opaque_symbol_handle!(
1435    /// Mirrors the `Metal` framework counterpart for `MetalIoScratchBuffer`.
1436    pub struct MetalIoScratchBuffer;
1437);
1438opaque_symbol_handle!(
1439    /// Mirrors the `Metal` framework counterpart for `MetalIoScratchBufferAllocator`.
1440    pub struct MetalIoScratchBufferAllocator;
1441);
1442opaque_symbol_handle!(
1443    /// Mirrors the `Metal` framework counterpart for `MetalLogContainer`.
1444    pub struct MetalLogContainer;
1445);
1446opaque_symbol_handle!(
1447    /// Mirrors the `Metal` framework counterpart for `MetalObjectPayloadBinding`.
1448    pub struct MetalObjectPayloadBinding;
1449);
1450opaque_symbol_handle!(
1451    /// Mirrors the `Metal` framework counterpart for `MetalParallelRenderCommandEncoder`.
1452    pub struct MetalParallelRenderCommandEncoder;
1453);
1454opaque_symbol_handle!(
1455    /// Mirrors the `Metal` framework counterpart for `MetalRasterizationRateMap`.
1456    pub struct MetalRasterizationRateMap;
1457);
1458opaque_symbol_handle!(
1459    /// Mirrors the `Metal` framework counterpart for `MetalResource`.
1460    pub struct MetalResource;
1461);
1462opaque_symbol_handle!(
1463    /// Mirrors the `Metal` framework counterpart for `MetalResourceStateCommandEncoder`.
1464    pub struct MetalResourceStateCommandEncoder;
1465);
1466opaque_symbol_handle!(
1467    /// Mirrors the `Metal` framework counterpart for `MetalResourceViewPool`.
1468    pub struct MetalResourceViewPool;
1469);
1470opaque_symbol_handle!(
1471    /// Mirrors the `Metal` framework counterpart for `MetalTensor`.
1472    pub struct MetalTensor;
1473);
1474opaque_symbol_handle!(
1475    /// Mirrors the `Metal` framework counterpart for `MetalTensorBinding`.
1476    pub struct MetalTensorBinding;
1477);
1478opaque_symbol_handle!(
1479    /// Mirrors the `Metal` framework counterpart for `MetalTextureBinding`.
1480    pub struct MetalTextureBinding;
1481);
1482opaque_symbol_handle!(
1483    /// Mirrors the `Metal` framework counterpart for `MetalTextureViewPool`.
1484    pub struct MetalTextureViewPool;
1485);
1486opaque_symbol_handle!(
1487    /// Mirrors the `Metal` framework counterpart for `MetalThreadgroupBinding`.
1488    pub struct MetalThreadgroupBinding;
1489);
1490opaque_symbol_class!(pub struct Metal4AccelerationStructureBoundingBoxGeometryDescriptor => "MTL4AccelerationStructureBoundingBoxGeometryDescriptor";);
1491opaque_symbol_class!(pub struct Metal4AccelerationStructureCurveGeometryDescriptor => "MTL4AccelerationStructureCurveGeometryDescriptor";);
1492opaque_symbol_class!(pub struct Metal4AccelerationStructureDescriptor => "MTL4AccelerationStructureDescriptor";);
1493opaque_symbol_class!(pub struct Metal4AccelerationStructureGeometryDescriptor => "MTL4AccelerationStructureGeometryDescriptor";);
1494opaque_symbol_class!(pub struct Metal4AccelerationStructureMotionBoundingBoxGeometryDescriptor => "MTL4AccelerationStructureMotionBoundingBoxGeometryDescriptor";);
1495opaque_symbol_class!(pub struct Metal4AccelerationStructureMotionCurveGeometryDescriptor => "MTL4AccelerationStructureMotionCurveGeometryDescriptor";);
1496opaque_symbol_class!(pub struct Metal4AccelerationStructureMotionTriangleGeometryDescriptor => "MTL4AccelerationStructureMotionTriangleGeometryDescriptor";);
1497opaque_symbol_class!(pub struct Metal4AccelerationStructureTriangleGeometryDescriptor => "MTL4AccelerationStructureTriangleGeometryDescriptor";);
1498opaque_symbol_class!(pub struct Metal4ArgumentTableDescriptor => "MTL4ArgumentTableDescriptor";);
1499opaque_symbol_class!(pub struct Metal4BinaryFunctionDescriptor => "MTL4BinaryFunctionDescriptor";);
1500opaque_symbol_class!(pub struct Metal4CommandAllocatorDescriptor => "MTL4CommandAllocatorDescriptor";);
1501opaque_symbol_class!(pub struct Metal4CommandBufferOptions => "MTL4CommandBufferOptions";);
1502opaque_symbol_class!(pub struct Metal4CommandQueueDescriptor => "MTL4CommandQueueDescriptor";);
1503opaque_symbol_class!(pub struct Metal4CommitOptions => "MTL4CommitOptions";);
1504opaque_symbol_class!(pub struct Metal4CompilerDescriptor => "MTL4CompilerDescriptor";);
1505opaque_symbol_class!(pub struct Metal4CompilerTaskOptions => "MTL4CompilerTaskOptions";);
1506opaque_symbol_class!(pub struct Metal4ComputePipelineDescriptor => "MTL4ComputePipelineDescriptor";);
1507opaque_symbol_class!(pub struct Metal4CounterHeapDescriptor => "MTL4CounterHeapDescriptor";);
1508opaque_symbol_class!(pub struct Metal4FunctionDescriptor => "MTL4FunctionDescriptor";);
1509opaque_symbol_class!(pub struct Metal4IndirectInstanceAccelerationStructureDescriptor => "MTL4IndirectInstanceAccelerationStructureDescriptor";);
1510opaque_symbol_class!(pub struct Metal4InstanceAccelerationStructureDescriptor => "MTL4InstanceAccelerationStructureDescriptor";);
1511opaque_symbol_class!(pub struct Metal4LibraryDescriptor => "MTL4LibraryDescriptor";);
1512opaque_symbol_class!(pub struct Metal4LibraryFunctionDescriptor => "MTL4LibraryFunctionDescriptor";);
1513opaque_symbol_class!(pub struct Metal4MachineLearningPipelineDescriptor => "MTL4MachineLearningPipelineDescriptor";);
1514opaque_symbol_class!(pub struct Metal4MachineLearningPipelineReflection => "MTL4MachineLearningPipelineReflection";);
1515opaque_symbol_class!(pub struct Metal4MeshRenderPipelineDescriptor => "MTL4MeshRenderPipelineDescriptor";);
1516opaque_symbol_class!(pub struct Metal4PipelineDataSetSerializerDescriptor => "MTL4PipelineDataSetSerializerDescriptor";);
1517opaque_symbol_class!(pub struct Metal4PipelineDescriptor => "MTL4PipelineDescriptor";);
1518opaque_symbol_class!(pub struct Metal4PipelineOptions => "MTL4PipelineOptions";);
1519opaque_symbol_class!(pub struct Metal4PipelineStageDynamicLinkingDescriptor => "MTL4PipelineStageDynamicLinkingDescriptor";);
1520opaque_symbol_class!(pub struct Metal4PrimitiveAccelerationStructureDescriptor => "MTL4PrimitiveAccelerationStructureDescriptor";);
1521opaque_symbol_class!(pub struct Metal4RenderPassDescriptor => "MTL4RenderPassDescriptor";);
1522opaque_symbol_class!(pub struct Metal4RenderPipelineBinaryFunctionsDescriptor => "MTL4RenderPipelineBinaryFunctionsDescriptor";);
1523opaque_symbol_class!(pub struct Metal4RenderPipelineColorAttachmentDescriptor => "MTL4RenderPipelineColorAttachmentDescriptor";);
1524opaque_symbol_class!(pub struct Metal4RenderPipelineColorAttachmentDescriptorArray => "MTL4RenderPipelineColorAttachmentDescriptorArray";);
1525opaque_symbol_class!(pub struct Metal4RenderPipelineDescriptor => "MTL4RenderPipelineDescriptor";);
1526opaque_symbol_class!(pub struct Metal4RenderPipelineDynamicLinkingDescriptor => "MTL4RenderPipelineDynamicLinkingDescriptor";);
1527opaque_symbol_class!(pub struct Metal4SpecializedFunctionDescriptor => "MTL4SpecializedFunctionDescriptor";);
1528opaque_symbol_class!(pub struct Metal4StaticLinkingDescriptor => "MTL4StaticLinkingDescriptor";);
1529opaque_symbol_class!(pub struct Metal4StitchedFunctionDescriptor => "MTL4StitchedFunctionDescriptor";);
1530opaque_symbol_class!(pub struct Metal4TileRenderPipelineDescriptor => "MTL4TileRenderPipelineDescriptor";);
1531opaque_symbol_class!(pub struct MetalAccelerationStructureBoundingBoxGeometryDescriptor => "MTLAccelerationStructureBoundingBoxGeometryDescriptor";);
1532opaque_symbol_class!(pub struct MetalAccelerationStructureCurveGeometryDescriptor => "MTLAccelerationStructureCurveGeometryDescriptor";);
1533opaque_symbol_class!(pub struct MetalAccelerationStructureDescriptor => "MTLAccelerationStructureDescriptor";);
1534opaque_symbol_class!(pub struct MetalAccelerationStructureGeometryDescriptor => "MTLAccelerationStructureGeometryDescriptor";);
1535opaque_symbol_class!(pub struct MetalAccelerationStructureMotionBoundingBoxGeometryDescriptor => "MTLAccelerationStructureMotionBoundingBoxGeometryDescriptor";);
1536opaque_symbol_class!(pub struct MetalAccelerationStructureMotionCurveGeometryDescriptor => "MTLAccelerationStructureMotionCurveGeometryDescriptor";);
1537opaque_symbol_class!(pub struct MetalAccelerationStructureMotionTriangleGeometryDescriptor => "MTLAccelerationStructureMotionTriangleGeometryDescriptor";);
1538opaque_symbol_class!(pub struct MetalAccelerationStructurePassDescriptor => "MTLAccelerationStructurePassDescriptor";);
1539opaque_symbol_class!(pub struct MetalAccelerationStructurePassSampleBufferAttachmentDescriptor => "MTLAccelerationStructurePassSampleBufferAttachmentDescriptor";);
1540opaque_symbol_class!(pub struct MetalAccelerationStructurePassSampleBufferAttachmentDescriptorArray => "MTLAccelerationStructurePassSampleBufferAttachmentDescriptorArray";);
1541opaque_symbol_class!(pub struct MetalAccelerationStructureTriangleGeometryDescriptor => "MTLAccelerationStructureTriangleGeometryDescriptor";);
1542opaque_symbol_class!(pub struct MetalArchitecture => "MTLArchitecture";);
1543opaque_symbol_class!(pub struct MetalArgument => "MTLArgument";);
1544opaque_symbol_class!(pub struct MetalArrayType => "MTLArrayType";);
1545opaque_symbol_class!(pub struct MetalAttribute => "MTLAttribute";);
1546opaque_symbol_class!(pub struct MetalAttributeDescriptor => "MTLAttributeDescriptor";);
1547opaque_symbol_class!(pub struct MetalAttributeDescriptorArray => "MTLAttributeDescriptorArray";);
1548opaque_symbol_class!(pub struct MetalBinaryArchiveDescriptor => "MTLBinaryArchiveDescriptor";);
1549opaque_symbol_class!(pub struct MetalBlitPassDescriptor => "MTLBlitPassDescriptor";);
1550opaque_symbol_class!(pub struct MetalBlitPassSampleBufferAttachmentDescriptor => "MTLBlitPassSampleBufferAttachmentDescriptor";);
1551opaque_symbol_class!(pub struct MetalBlitPassSampleBufferAttachmentDescriptorArray => "MTLBlitPassSampleBufferAttachmentDescriptorArray";);
1552opaque_symbol_class!(pub struct MetalBufferLayoutDescriptor => "MTLBufferLayoutDescriptor";);
1553opaque_symbol_class!(pub struct MetalBufferLayoutDescriptorArray => "MTLBufferLayoutDescriptorArray";);
1554opaque_symbol_class!(
1555    /// `MTLCaptureDescriptor` — configures a GPU capture session.
1556    pub struct MetalCaptureDescriptor => "MTLCaptureDescriptor";
1557);
1558opaque_symbol_class!(pub struct MetalCommandBufferDescriptor => "MTLCommandBufferDescriptor";);
1559opaque_symbol_class!(pub struct MetalCommandQueueDescriptor => "MTLCommandQueueDescriptor";);
1560opaque_symbol_class!(pub struct MetalCompileOptions => "MTLCompileOptions";);
1561opaque_symbol_class!(pub struct MetalComputePassDescriptor => "MTLComputePassDescriptor";);
1562opaque_symbol_class!(pub struct MetalComputePassSampleBufferAttachmentDescriptor => "MTLComputePassSampleBufferAttachmentDescriptor";);
1563opaque_symbol_class!(pub struct MetalComputePassSampleBufferAttachmentDescriptorArray => "MTLComputePassSampleBufferAttachmentDescriptorArray";);
1564opaque_symbol_class!(pub struct MetalComputePipelineReflection => "MTLComputePipelineReflection";);
1565opaque_symbol_class!(pub struct MetalCounterSampleBufferDescriptor => "MTLCounterSampleBufferDescriptor";);
1566opaque_symbol_class!(pub struct MetalFunctionConstant => "MTLFunctionConstant";);
1567opaque_symbol_class!(pub struct MetalFunctionConstantValues => "MTLFunctionConstantValues";);
1568opaque_symbol_class!(pub struct MetalFunctionDescriptor => "MTLFunctionDescriptor";);
1569opaque_symbol_class!(pub struct MetalFunctionReflection => "MTLFunctionReflection";);
1570opaque_symbol_class!(pub struct MetalFunctionStitchingAttributeAlwaysInline => "MTLFunctionStitchingAttributeAlwaysInline";);
1571opaque_symbol_class!(pub struct MetalFunctionStitchingFunctionNode => "MTLFunctionStitchingFunctionNode";);
1572opaque_symbol_class!(pub struct MetalFunctionStitchingGraph => "MTLFunctionStitchingGraph";);
1573opaque_symbol_class!(pub struct MetalFunctionStitchingInputNode => "MTLFunctionStitchingInputNode";);
1574opaque_symbol_class!(pub struct MetalFxFrameInterpolatorDescriptor => "MTLFXFrameInterpolatorDescriptor";);
1575opaque_symbol_class!(pub struct MetalFxTemporalDenoisedScalerDescriptor => "MTLFXTemporalDenoisedScalerDescriptor";);
1576opaque_symbol_class!(pub struct MetalHeapDescriptor => "MTLHeapDescriptor";);
1577opaque_symbol_class!(pub struct MetalIndirectCommandBufferDescriptor => "MTLIndirectCommandBufferDescriptor";);
1578opaque_symbol_class!(pub struct MetalIndirectInstanceAccelerationStructureDescriptor => "MTLIndirectInstanceAccelerationStructureDescriptor";);
1579opaque_symbol_class!(pub struct MetalInstanceAccelerationStructureDescriptor => "MTLInstanceAccelerationStructureDescriptor";);
1580opaque_symbol_class!(pub struct MetalIntersectionFunctionDescriptor => "MTLIntersectionFunctionDescriptor";);
1581opaque_symbol_class!(pub struct MetalIntersectionFunctionTableDescriptor => "MTLIntersectionFunctionTableDescriptor";);
1582opaque_symbol_class!(pub struct MetalIoCommandQueueDescriptor => "MTLIOCommandQueueDescriptor";);
1583opaque_symbol_class!(pub struct MetalLinkedFunctions => "MTLLinkedFunctions";);
1584opaque_symbol_class!(pub struct MetalLogStateDescriptor => "MTLLogStateDescriptor";);
1585opaque_symbol_class!(pub struct MetalLogicalToPhysicalColorAttachmentMap => "MTLLogicalToPhysicalColorAttachmentMap";);
1586opaque_symbol_class!(pub struct MetalMeshRenderPipelineDescriptor => "MTLMeshRenderPipelineDescriptor";);
1587opaque_symbol_class!(pub struct MetalMotionKeyframeData => "MTLMotionKeyframeData";);
1588opaque_symbol_class!(pub struct MetalPipelineBufferDescriptor => "MTLPipelineBufferDescriptor";);
1589opaque_symbol_class!(pub struct MetalPipelineBufferDescriptorArray => "MTLPipelineBufferDescriptorArray";);
1590opaque_symbol_class!(pub struct MetalPointerType => "MTLPointerType";);
1591opaque_symbol_class!(pub struct MetalPrimitiveAccelerationStructureDescriptor => "MTLPrimitiveAccelerationStructureDescriptor";);
1592opaque_symbol_class!(pub struct MetalRasterizationRateLayerArray => "MTLRasterizationRateLayerArray";);
1593opaque_symbol_handle!(
1594    pub struct MetalRasterizationRateLayerDescriptor;
1595);
1596
1597impl MetalRasterizationRateLayerDescriptor {
1598    #[must_use]
1599    pub fn with_sample_count(horizontal: usize, vertical: usize) -> Option<Self> {
1600        const MAX_SAMPLES: usize = 16_384;
1601        if horizontal == 0 || vertical == 0 || horizontal > MAX_SAMPLES || vertical > MAX_SAMPLES {
1602            return None;
1603        }
1604        Self::wrap(unsafe {
1605            ffi::ametal_rasterization_rate_layer_descriptor_new(horizontal, vertical)
1606        })
1607    }
1608}
1609opaque_symbol_class!(pub struct MetalRasterizationRateMapDescriptor => "MTLRasterizationRateMapDescriptor";);
1610opaque_symbol_class!(pub struct MetalRasterizationRateSampleArray => "MTLRasterizationRateSampleArray";);
1611opaque_symbol_class!(pub struct MetalRenderPassAttachmentDescriptor => "MTLRenderPassAttachmentDescriptor";);
1612opaque_symbol_class!(pub struct MetalRenderPassColorAttachmentDescriptor => "MTLRenderPassColorAttachmentDescriptor";);
1613opaque_symbol_class!(pub struct MetalRenderPassColorAttachmentDescriptorArray => "MTLRenderPassColorAttachmentDescriptorArray";);
1614opaque_symbol_class!(pub struct MetalRenderPassDepthAttachmentDescriptor => "MTLRenderPassDepthAttachmentDescriptor";);
1615opaque_symbol_class!(pub struct MetalRenderPassDescriptor => "MTLRenderPassDescriptor";);
1616opaque_symbol_class!(pub struct MetalRenderPassSampleBufferAttachmentDescriptor => "MTLRenderPassSampleBufferAttachmentDescriptor";);
1617opaque_symbol_class!(pub struct MetalRenderPassSampleBufferAttachmentDescriptorArray => "MTLRenderPassSampleBufferAttachmentDescriptorArray";);
1618opaque_symbol_class!(pub struct MetalRenderPassStencilAttachmentDescriptor => "MTLRenderPassStencilAttachmentDescriptor";);
1619opaque_symbol_class!(pub struct MetalRenderPipelineColorAttachmentDescriptorArray => "MTLRenderPipelineColorAttachmentDescriptorArray";);
1620opaque_symbol_class!(pub struct MetalRenderPipelineFunctionsDescriptor => "MTLRenderPipelineFunctionsDescriptor";);
1621opaque_symbol_class!(pub struct MetalRenderPipelineReflection => "MTLRenderPipelineReflection";);
1622opaque_symbol_class!(pub struct MetalResidencySetDescriptor => "MTLResidencySetDescriptor";);
1623opaque_symbol_class!(pub struct MetalResourceStatePassDescriptor => "MTLResourceStatePassDescriptor";);
1624opaque_symbol_class!(pub struct MetalResourceStatePassSampleBufferAttachmentDescriptor => "MTLResourceStatePassSampleBufferAttachmentDescriptor";);
1625opaque_symbol_class!(pub struct MetalResourceStatePassSampleBufferAttachmentDescriptorArray => "MTLResourceStatePassSampleBufferAttachmentDescriptorArray";);
1626opaque_symbol_class!(pub struct MetalResourceViewPoolDescriptor => "MTLResourceViewPoolDescriptor";);
1627opaque_symbol_class!(pub struct MetalSharedEventHandle => "MTLSharedEventHandle";);
1628opaque_symbol_class!(pub struct MetalSharedEventListener => "MTLSharedEventListener";);
1629opaque_symbol_class!(pub struct MetalSharedTextureHandle => "MTLSharedTextureHandle";);
1630opaque_symbol_class!(pub struct MetalStageInputOutputDescriptor => "MTLStageInputOutputDescriptor";);
1631opaque_symbol_class!(pub struct MetalStitchedLibraryDescriptor => "MTLStitchedLibraryDescriptor";);
1632opaque_symbol_class!(pub struct MetalStructMember => "MTLStructMember";);
1633opaque_symbol_class!(pub struct MetalStructType => "MTLStructType";);
1634opaque_symbol_class!(pub struct MetalTensorDescriptor => "MTLTensorDescriptor";);
1635opaque_symbol_class!(pub struct MetalTensorExtents => "MTLTensorExtents";);
1636opaque_symbol_class!(pub struct MetalTensorReferenceType => "MTLTensorReferenceType";);
1637opaque_symbol_class!(pub struct MetalTextureReferenceType => "MTLTextureReferenceType";);
1638opaque_symbol_class!(pub struct MetalTextureViewDescriptor => "MTLTextureViewDescriptor";);
1639opaque_symbol_class!(pub struct MetalTileRenderPipelineColorAttachmentDescriptorArray => "MTLTileRenderPipelineColorAttachmentDescriptorArray";);
1640opaque_symbol_class!(pub struct MetalType => "MTLType";);
1641opaque_symbol_class!(pub struct MetalVertexAttribute => "MTLVertexAttribute";);
1642opaque_symbol_class!(pub struct MetalVertexAttributeDescriptor => "MTLVertexAttributeDescriptor";);
1643opaque_symbol_class!(pub struct MetalVertexAttributeDescriptorArray => "MTLVertexAttributeDescriptorArray";);
1644opaque_symbol_class!(pub struct MetalVertexBufferLayoutDescriptor => "MTLVertexBufferLayoutDescriptor";);
1645opaque_symbol_class!(pub struct MetalVertexBufferLayoutDescriptorArray => "MTLVertexBufferLayoutDescriptorArray";);
1646opaque_symbol_class!(pub struct MetalVertexDescriptor => "MTLVertexDescriptor";);
1647opaque_symbol_class!(pub struct MetalVisibleFunctionTableDescriptor => "MTLVisibleFunctionTableDescriptor";);