Skip to main content

mtl_gpu/pipeline/
functions_descriptor.rs

1//! Pipeline functions descriptors and utilities.
2//!
3//! This module contains:
4//! - `RenderPipelineFunctionsDescriptor` for specifying additional shader functions
5//! - `LogicalToPhysicalColorAttachmentMap` for remapping color attachments
6
7use std::ffi::c_void;
8use std::ptr::NonNull;
9
10use mtl_foundation::{Referencing, UInteger};
11use mtl_sys::{msg_send_0, msg_send_1, sel};
12
13pub struct RenderPipelineFunctionsDescriptor(pub(crate) NonNull<c_void>);
14
15impl RenderPipelineFunctionsDescriptor {
16    /// Create a new render pipeline functions descriptor.
17    ///
18    /// C++ equivalent: `static RenderPipelineFunctionsDescriptor* alloc()->init()`
19    pub fn new() -> Option<Self> {
20        unsafe {
21            let class = mtl_sys::Class::get("MTLRenderPipelineFunctionsDescriptor")?;
22            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
23            if ptr.is_null() {
24                return None;
25            }
26            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
27            Self::from_raw(ptr)
28        }
29    }
30
31    /// Create from a raw pointer.
32    ///
33    /// # Safety
34    ///
35    /// The pointer must be a valid render pipeline functions descriptor object.
36    #[inline]
37    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
38        NonNull::new(ptr).map(Self)
39    }
40
41    /// Get the raw pointer.
42    #[inline]
43    pub fn as_raw(&self) -> *mut c_void {
44        self.0.as_ptr()
45    }
46
47    // =========================================================================
48    // Additional Binary Functions (Raw)
49    // =========================================================================
50
51    /// Get the vertex additional binary functions array (raw pointer).
52    ///
53    /// C++ equivalent: `NS::Array* vertexAdditionalBinaryFunctions() const`
54    pub fn vertex_additional_binary_functions_raw(&self) -> *mut c_void {
55        unsafe { msg_send_0(self.as_ptr(), sel!(vertexAdditionalBinaryFunctions)) }
56    }
57
58    /// Set the vertex additional binary functions array (raw pointer).
59    ///
60    /// C++ equivalent: `void setVertexAdditionalBinaryFunctions(const NS::Array*)`
61    ///
62    /// # Safety
63    ///
64    /// The pointer must be a valid NS::Array of BinaryFunction objects.
65    pub unsafe fn set_vertex_additional_binary_functions_raw(&self, functions: *const c_void) {
66        unsafe {
67            let _: () = msg_send_1(
68                self.as_ptr(),
69                sel!(setVertexAdditionalBinaryFunctions:),
70                functions,
71            );
72        }
73    }
74
75    /// Get the fragment additional binary functions array (raw pointer).
76    ///
77    /// C++ equivalent: `NS::Array* fragmentAdditionalBinaryFunctions() const`
78    pub fn fragment_additional_binary_functions_raw(&self) -> *mut c_void {
79        unsafe { msg_send_0(self.as_ptr(), sel!(fragmentAdditionalBinaryFunctions)) }
80    }
81
82    /// Set the fragment additional binary functions array (raw pointer).
83    ///
84    /// C++ equivalent: `void setFragmentAdditionalBinaryFunctions(const NS::Array*)`
85    ///
86    /// # Safety
87    ///
88    /// The pointer must be a valid NS::Array of BinaryFunction objects.
89    pub unsafe fn set_fragment_additional_binary_functions_raw(&self, functions: *const c_void) {
90        unsafe {
91            let _: () = msg_send_1(
92                self.as_ptr(),
93                sel!(setFragmentAdditionalBinaryFunctions:),
94                functions,
95            );
96        }
97    }
98
99    /// Get the tile additional binary functions array (raw pointer).
100    ///
101    /// C++ equivalent: `NS::Array* tileAdditionalBinaryFunctions() const`
102    pub fn tile_additional_binary_functions_raw(&self) -> *mut c_void {
103        unsafe { msg_send_0(self.as_ptr(), sel!(tileAdditionalBinaryFunctions)) }
104    }
105
106    /// Set the tile additional binary functions array (raw pointer).
107    ///
108    /// C++ equivalent: `void setTileAdditionalBinaryFunctions(const NS::Array*)`
109    ///
110    /// # Safety
111    ///
112    /// The pointer must be a valid NS::Array of BinaryFunction objects.
113    pub unsafe fn set_tile_additional_binary_functions_raw(&self, functions: *const c_void) {
114        unsafe {
115            let _: () = msg_send_1(
116                self.as_ptr(),
117                sel!(setTileAdditionalBinaryFunctions:),
118                functions,
119            );
120        }
121    }
122}
123
124impl Default for RenderPipelineFunctionsDescriptor {
125    fn default() -> Self {
126        Self::new().expect("failed to create RenderPipelineFunctionsDescriptor")
127    }
128}
129
130impl Clone for RenderPipelineFunctionsDescriptor {
131    fn clone(&self) -> Self {
132        unsafe {
133            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
134            Self::from_raw(ptr).expect("copy returned null")
135        }
136    }
137}
138
139impl Drop for RenderPipelineFunctionsDescriptor {
140    fn drop(&mut self) {
141        unsafe {
142            msg_send_0::<()>(self.as_ptr(), sel!(release));
143        }
144    }
145}
146
147impl Referencing for RenderPipelineFunctionsDescriptor {
148    #[inline]
149    fn as_ptr(&self) -> *const c_void {
150        self.0.as_ptr()
151    }
152}
153
154unsafe impl Send for RenderPipelineFunctionsDescriptor {}
155unsafe impl Sync for RenderPipelineFunctionsDescriptor {}
156
157impl std::fmt::Debug for RenderPipelineFunctionsDescriptor {
158    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
159        f.debug_struct("RenderPipelineFunctionsDescriptor").finish()
160    }
161}
162
163// ============================================================================
164// LogicalToPhysicalColorAttachmentMap
165// ============================================================================
166
167/// Maps logical color attachment indices to physical indices.
168///
169/// C++ equivalent: `MTL::LogicalToPhysicalColorAttachmentMap`
170#[repr(transparent)]
171pub struct LogicalToPhysicalColorAttachmentMap(pub(crate) NonNull<c_void>);
172
173impl LogicalToPhysicalColorAttachmentMap {
174    /// Allocate a new logical to physical color attachment map.
175    ///
176    /// C++ equivalent: `static LogicalToPhysicalColorAttachmentMap* alloc()`
177    pub fn alloc() -> Option<Self> {
178        unsafe {
179            let cls = mtl_sys::Class::get("MTLLogicalToPhysicalColorAttachmentMap")?;
180            let ptr: *mut c_void = msg_send_0(cls.as_ptr(), sel!(alloc));
181            Self::from_raw(ptr)
182        }
183    }
184
185    /// Initialize an allocated map.
186    ///
187    /// C++ equivalent: `LogicalToPhysicalColorAttachmentMap* init()`
188    pub fn init(&self) -> Option<Self> {
189        unsafe {
190            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(init));
191            Self::from_raw(ptr)
192        }
193    }
194
195    /// Create a new logical to physical color attachment map.
196    pub fn new() -> Option<Self> {
197        Self::alloc()?.init()
198    }
199
200    /// Create from a raw pointer.
201    ///
202    /// # Safety
203    ///
204    /// The pointer must be a valid Metal logical to physical color attachment map.
205    #[inline]
206    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
207        NonNull::new(ptr).map(Self)
208    }
209
210    /// Get the raw pointer.
211    #[inline]
212    pub fn as_raw(&self) -> *mut c_void {
213        self.0.as_ptr()
214    }
215
216    /// Get the physical index for a logical index.
217    ///
218    /// C++ equivalent: `NS::UInteger getPhysicalIndex(NS::UInteger logicalIndex)`
219    #[inline]
220    pub fn physical_index(&self, logical_index: UInteger) -> UInteger {
221        unsafe { msg_send_1(self.as_ptr(), sel!(getPhysicalIndex:), logical_index) }
222    }
223
224    /// Set the physical index for a logical index.
225    ///
226    /// C++ equivalent: `void setPhysicalIndex(NS::UInteger physicalIndex, NS::UInteger logicalIndex)`
227    #[inline]
228    pub fn set_physical_index(&self, physical_index: UInteger, logical_index: UInteger) {
229        unsafe {
230            let _: () = mtl_sys::msg_send_2(
231                self.as_ptr(),
232                sel!(setPhysicalIndex: forLogicalIndex:),
233                physical_index,
234                logical_index,
235            );
236        }
237    }
238
239    /// Reset the map to default values.
240    ///
241    /// C++ equivalent: `void reset()`
242    #[inline]
243    pub fn reset(&self) {
244        unsafe {
245            msg_send_0::<()>(self.as_ptr(), sel!(reset));
246        }
247    }
248}
249
250impl Default for LogicalToPhysicalColorAttachmentMap {
251    fn default() -> Self {
252        Self::new().expect("failed to create LogicalToPhysicalColorAttachmentMap")
253    }
254}
255
256impl Clone for LogicalToPhysicalColorAttachmentMap {
257    fn clone(&self) -> Self {
258        unsafe {
259            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
260            Self::from_raw(ptr).expect("copy returned null")
261        }
262    }
263}
264
265impl Drop for LogicalToPhysicalColorAttachmentMap {
266    fn drop(&mut self) {
267        unsafe {
268            msg_send_0::<()>(self.as_ptr(), sel!(release));
269        }
270    }
271}
272
273impl Referencing for LogicalToPhysicalColorAttachmentMap {
274    #[inline]
275    fn as_ptr(&self) -> *const c_void {
276        self.0.as_ptr()
277    }
278}
279
280unsafe impl Send for LogicalToPhysicalColorAttachmentMap {}
281unsafe impl Sync for LogicalToPhysicalColorAttachmentMap {}
282
283impl std::fmt::Debug for LogicalToPhysicalColorAttachmentMap {
284    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
285        f.debug_struct("LogicalToPhysicalColorAttachmentMap")
286            .finish()
287    }
288}