Skip to main content

mtl_gpu/mtl4/compiler/
descriptor.rs

1//! MTL4 Compiler descriptor.
2
3use std::ffi::c_void;
4use std::ptr::NonNull;
5
6use mtl_foundation::Referencing;
7use mtl_sys::{msg_send_0, msg_send_1, sel};
8
9use crate::mtl4::PipelineDataSetSerializer;
10
11/// Descriptor for creating a compiler.
12///
13/// C++ equivalent: `MTL4::CompilerDescriptor`
14#[repr(transparent)]
15pub struct CompilerDescriptor(NonNull<c_void>);
16
17impl CompilerDescriptor {
18    /// Create a CompilerDescriptor from a raw pointer.
19    #[inline]
20    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
21        NonNull::new(ptr).map(Self)
22    }
23
24    /// Get the raw pointer.
25    #[inline]
26    pub fn as_raw(&self) -> *mut c_void {
27        self.0.as_ptr()
28    }
29
30    /// Create a new compiler descriptor.
31    pub fn new() -> Option<Self> {
32        unsafe {
33            let class = mtl_sys::Class::get("MTL4CompilerDescriptor")?;
34            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
35            if ptr.is_null() {
36                return None;
37            }
38            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
39            Self::from_raw(ptr)
40        }
41    }
42
43    /// Get the label.
44    ///
45    /// C++ equivalent: `NS::String* label() const`
46    pub fn label(&self) -> Option<String> {
47        unsafe {
48            let ns_string: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
49            if ns_string.is_null() {
50                return None;
51            }
52            let c_str: *const i8 = msg_send_0(ns_string, sel!(UTF8String));
53            if c_str.is_null() {
54                return None;
55            }
56            Some(
57                std::ffi::CStr::from_ptr(c_str)
58                    .to_string_lossy()
59                    .into_owned(),
60            )
61        }
62    }
63
64    /// Set the label.
65    ///
66    /// C++ equivalent: `void setLabel(const NS::String*)`
67    pub fn set_label(&self, label: &str) {
68        if let Some(ns_label) = mtl_foundation::String::from_str(label) {
69            unsafe {
70                let _: () = msg_send_1(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
71            }
72        }
73    }
74
75    /// Get the pipeline data set serializer.
76    ///
77    /// C++ equivalent: `PipelineDataSetSerializer* pipelineDataSetSerializer() const`
78    pub fn pipeline_data_set_serializer(&self) -> Option<PipelineDataSetSerializer> {
79        unsafe {
80            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(pipelineDataSetSerializer));
81            PipelineDataSetSerializer::from_raw(ptr)
82        }
83    }
84
85    /// Set the pipeline data set serializer.
86    ///
87    /// C++ equivalent: `void setPipelineDataSetSerializer(const MTL4::PipelineDataSetSerializer*)`
88    pub fn set_pipeline_data_set_serializer(&self, serializer: &PipelineDataSetSerializer) {
89        unsafe {
90            let _: () = msg_send_1(
91                self.as_ptr(),
92                sel!(setPipelineDataSetSerializer:),
93                serializer.as_ptr(),
94            );
95        }
96    }
97}
98
99impl Clone for CompilerDescriptor {
100    fn clone(&self) -> Self {
101        unsafe {
102            mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
103        }
104        Self(self.0)
105    }
106}
107
108impl Drop for CompilerDescriptor {
109    fn drop(&mut self) {
110        unsafe {
111            mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
112        }
113    }
114}
115
116impl Referencing for CompilerDescriptor {
117    #[inline]
118    fn as_ptr(&self) -> *const c_void {
119        self.0.as_ptr()
120    }
121}
122
123unsafe impl Send for CompilerDescriptor {}
124unsafe impl Sync for CompilerDescriptor {}
125
126impl std::fmt::Debug for CompilerDescriptor {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        f.debug_struct("CompilerDescriptor")
129            .field("label", &self.label())
130            .finish()
131    }
132}