Skip to main content

mtl_gpu/pipeline/
reflection.rs

1//! Pipeline reflection types.
2//!
3//! Corresponds to `MTL::ComputePipelineReflection` and `MTL::RenderPipelineReflection`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::Referencing;
9use mtl_sys::{msg_send_0, sel};
10
11pub struct ComputePipelineReflection(pub(crate) NonNull<c_void>);
12
13impl ComputePipelineReflection {
14    /// Create a new compute pipeline reflection.
15    ///
16    /// C++ equivalent: `static ComputePipelineReflection* alloc()->init()`
17    pub fn new() -> Option<Self> {
18        unsafe {
19            let class = mtl_sys::Class::get("MTLComputePipelineReflection")?;
20            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
21            if ptr.is_null() {
22                return None;
23            }
24            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
25            Self::from_raw(ptr)
26        }
27    }
28
29    /// Create a ComputePipelineReflection from a raw pointer.
30    ///
31    /// # Safety
32    ///
33    /// The pointer must be a valid Metal compute pipeline reflection object.
34    #[inline]
35    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
36        NonNull::new(ptr).map(Self)
37    }
38
39    /// Get the raw pointer to the reflection.
40    #[inline]
41    pub fn as_raw(&self) -> *mut c_void {
42        self.0.as_ptr()
43    }
44
45    // =========================================================================
46    // Properties
47    // =========================================================================
48
49    /// Get the arguments array (deprecated, use bindings instead).
50    ///
51    /// Returns an array of MTLArgument objects.
52    ///
53    /// C++ equivalent: `NS::Array* arguments() const`
54    pub fn arguments_raw(&self) -> *mut c_void {
55        unsafe { msg_send_0(self.as_ptr(), sel!(arguments)) }
56    }
57
58    /// Get the bindings array.
59    ///
60    /// Returns an array of objects conforming to MTLBinding protocol.
61    ///
62    /// C++ equivalent: `NS::Array* bindings() const`
63    pub fn bindings_raw(&self) -> *mut c_void {
64        unsafe { msg_send_0(self.as_ptr(), sel!(bindings)) }
65    }
66}
67
68impl Clone for ComputePipelineReflection {
69    fn clone(&self) -> Self {
70        unsafe {
71            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
72        }
73        Self(self.0)
74    }
75}
76
77impl Drop for ComputePipelineReflection {
78    fn drop(&mut self) {
79        unsafe {
80            msg_send_0::<()>(self.as_ptr(), sel!(release));
81        }
82    }
83}
84
85impl Referencing for ComputePipelineReflection {
86    #[inline]
87    fn as_ptr(&self) -> *const c_void {
88        self.0.as_ptr()
89    }
90}
91
92unsafe impl Send for ComputePipelineReflection {}
93unsafe impl Sync for ComputePipelineReflection {}
94
95impl std::fmt::Debug for ComputePipelineReflection {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        f.debug_struct("ComputePipelineReflection").finish()
98    }
99}
100
101// ============================================================================
102// RenderPipelineReflection
103// ============================================================================
104
105/// Reflection information for a render pipeline.
106///
107/// C++ equivalent: `MTL::RenderPipelineReflection`
108#[repr(transparent)]
109pub struct RenderPipelineReflection(pub(crate) NonNull<c_void>);
110
111impl RenderPipelineReflection {
112    /// Create a new render pipeline reflection.
113    ///
114    /// C++ equivalent: `static RenderPipelineReflection* alloc()->init()`
115    pub fn new() -> Option<Self> {
116        unsafe {
117            let class = mtl_sys::Class::get("MTLRenderPipelineReflection")?;
118            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
119            if ptr.is_null() {
120                return None;
121            }
122            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
123            Self::from_raw(ptr)
124        }
125    }
126
127    /// Create a RenderPipelineReflection from a raw pointer.
128    ///
129    /// # Safety
130    ///
131    /// The pointer must be a valid Metal render pipeline reflection object.
132    #[inline]
133    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
134        NonNull::new(ptr).map(Self)
135    }
136
137    /// Get the raw pointer to the reflection.
138    #[inline]
139    pub fn as_raw(&self) -> *mut c_void {
140        self.0.as_ptr()
141    }
142
143    // =========================================================================
144    // Properties - Arguments (deprecated)
145    // =========================================================================
146
147    /// Get the vertex arguments array (deprecated, use vertex_bindings instead).
148    ///
149    /// C++ equivalent: `NS::Array* vertexArguments() const`
150    pub fn vertex_arguments_raw(&self) -> *mut c_void {
151        unsafe { msg_send_0(self.as_ptr(), sel!(vertexArguments)) }
152    }
153
154    /// Get the fragment arguments array (deprecated, use fragment_bindings instead).
155    ///
156    /// C++ equivalent: `NS::Array* fragmentArguments() const`
157    pub fn fragment_arguments_raw(&self) -> *mut c_void {
158        unsafe { msg_send_0(self.as_ptr(), sel!(fragmentArguments)) }
159    }
160
161    /// Get the tile arguments array (deprecated, use tile_bindings instead).
162    ///
163    /// C++ equivalent: `NS::Array* tileArguments() const`
164    pub fn tile_arguments_raw(&self) -> *mut c_void {
165        unsafe { msg_send_0(self.as_ptr(), sel!(tileArguments)) }
166    }
167
168    // =========================================================================
169    // Properties - Bindings
170    // =========================================================================
171
172    /// Get the vertex bindings array.
173    ///
174    /// C++ equivalent: `NS::Array* vertexBindings() const`
175    pub fn vertex_bindings_raw(&self) -> *mut c_void {
176        unsafe { msg_send_0(self.as_ptr(), sel!(vertexBindings)) }
177    }
178
179    /// Get the fragment bindings array.
180    ///
181    /// C++ equivalent: `NS::Array* fragmentBindings() const`
182    pub fn fragment_bindings_raw(&self) -> *mut c_void {
183        unsafe { msg_send_0(self.as_ptr(), sel!(fragmentBindings)) }
184    }
185
186    /// Get the tile bindings array.
187    ///
188    /// C++ equivalent: `NS::Array* tileBindings() const`
189    pub fn tile_bindings_raw(&self) -> *mut c_void {
190        unsafe { msg_send_0(self.as_ptr(), sel!(tileBindings)) }
191    }
192
193    /// Get the object bindings array.
194    ///
195    /// C++ equivalent: `NS::Array* objectBindings() const`
196    pub fn object_bindings_raw(&self) -> *mut c_void {
197        unsafe { msg_send_0(self.as_ptr(), sel!(objectBindings)) }
198    }
199
200    /// Get the mesh bindings array.
201    ///
202    /// C++ equivalent: `NS::Array* meshBindings() const`
203    pub fn mesh_bindings_raw(&self) -> *mut c_void {
204        unsafe { msg_send_0(self.as_ptr(), sel!(meshBindings)) }
205    }
206}
207
208impl Clone for RenderPipelineReflection {
209    fn clone(&self) -> Self {
210        unsafe {
211            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
212        }
213        Self(self.0)
214    }
215}
216
217impl Drop for RenderPipelineReflection {
218    fn drop(&mut self) {
219        unsafe {
220            msg_send_0::<()>(self.as_ptr(), sel!(release));
221        }
222    }
223}
224
225impl Referencing for RenderPipelineReflection {
226    #[inline]
227    fn as_ptr(&self) -> *const c_void {
228        self.0.as_ptr()
229    }
230}
231
232unsafe impl Send for RenderPipelineReflection {}
233unsafe impl Sync for RenderPipelineReflection {}
234
235impl std::fmt::Debug for RenderPipelineReflection {
236    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237        f.debug_struct("RenderPipelineReflection").finish()
238    }
239}