Skip to main content

mtl_gpu/mtl4/
function_descriptor.rs

1//! MTL4 FunctionDescriptor implementation.
2//!
3//! Corresponds to `Metal/MTL4FunctionDescriptor.hpp`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::Referencing;
9use mtl_sys::{msg_send_0, sel};
10
11// ============================================================
12// FunctionDescriptor
13// ============================================================
14
15/// Descriptor for MTL4 functions.
16///
17/// C++ equivalent: `MTL4::FunctionDescriptor`
18///
19/// FunctionDescriptor is used to specify a function for pipeline creation
20/// in Metal 4.
21#[repr(transparent)]
22pub struct FunctionDescriptor(NonNull<c_void>);
23
24impl FunctionDescriptor {
25    /// Create a FunctionDescriptor from a raw pointer.
26    #[inline]
27    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
28        NonNull::new(ptr).map(Self)
29    }
30
31    /// Get the raw pointer.
32    #[inline]
33    pub fn as_raw(&self) -> *mut c_void {
34        self.0.as_ptr()
35    }
36
37    /// Create a new function descriptor.
38    pub fn new() -> Option<Self> {
39        unsafe {
40            let class = mtl_sys::Class::get("MTL4FunctionDescriptor")?;
41            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
42            if ptr.is_null() {
43                return None;
44            }
45            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
46            Self::from_raw(ptr)
47        }
48    }
49}
50
51impl Clone for FunctionDescriptor {
52    fn clone(&self) -> Self {
53        unsafe {
54            mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
55        }
56        Self(self.0)
57    }
58}
59
60impl Drop for FunctionDescriptor {
61    fn drop(&mut self) {
62        unsafe {
63            mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
64        }
65    }
66}
67
68impl Referencing for FunctionDescriptor {
69    #[inline]
70    fn as_ptr(&self) -> *const c_void {
71        self.0.as_ptr()
72    }
73}
74
75unsafe impl Send for FunctionDescriptor {}
76unsafe impl Sync for FunctionDescriptor {}
77
78impl std::fmt::Debug for FunctionDescriptor {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        f.debug_struct("FunctionDescriptor").finish()
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn test_function_descriptor_size() {
90        assert_eq!(
91            std::mem::size_of::<FunctionDescriptor>(),
92            std::mem::size_of::<*mut c_void>()
93        );
94    }
95}