Skip to main content

mtl_gpu/pass/
attachment.rs

1//! Base class for render pass attachment descriptors.
2
3use std::ffi::c_void;
4use std::ptr::NonNull;
5
6use mtl_foundation::{Referencing, UInteger};
7use mtl_sys::{msg_send_0, msg_send_1, sel};
8
9use crate::Texture;
10use crate::enums::{LoadAction, StoreAction, StoreActionOptions};
11
12/// Base class for render pass attachment descriptors.
13///
14/// C++ equivalent: `MTL::RenderPassAttachmentDescriptor`
15#[repr(transparent)]
16pub struct RenderPassAttachmentDescriptor(pub(crate) NonNull<c_void>);
17
18impl RenderPassAttachmentDescriptor {
19    /// Create a RenderPassAttachmentDescriptor from a raw pointer.
20    ///
21    /// # Safety
22    ///
23    /// The pointer must be a valid Metal render pass attachment descriptor object.
24    #[inline]
25    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
26        NonNull::new(ptr).map(Self)
27    }
28
29    /// Get the raw pointer.
30    #[inline]
31    pub fn as_raw(&self) -> *mut c_void {
32        self.0.as_ptr()
33    }
34
35    // =========================================================================
36    // Properties
37    // =========================================================================
38
39    /// Get the texture for this attachment.
40    ///
41    /// C++ equivalent: `Texture* texture() const`
42    pub fn texture(&self) -> Option<Texture> {
43        unsafe {
44            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(texture));
45            if ptr.is_null() {
46                return None;
47            }
48            let _: *mut c_void = msg_send_0(ptr, sel!(retain));
49            Texture::from_raw(ptr)
50        }
51    }
52
53    /// Set the texture for this attachment.
54    ///
55    /// C++ equivalent: `void setTexture(const Texture*)`
56    pub fn set_texture(&self, texture: Option<&Texture>) {
57        unsafe {
58            let ptr = texture.map_or(std::ptr::null(), |t| t.as_ptr());
59            msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setTexture:), ptr);
60        }
61    }
62
63    /// Get the mipmap level for this attachment.
64    ///
65    /// C++ equivalent: `NS::UInteger level() const`
66    #[inline]
67    pub fn level(&self) -> UInteger {
68        unsafe { msg_send_0(self.as_ptr(), sel!(level)) }
69    }
70
71    /// Set the mipmap level for this attachment.
72    ///
73    /// C++ equivalent: `void setLevel(NS::UInteger)`
74    #[inline]
75    pub fn set_level(&self, level: UInteger) {
76        unsafe {
77            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setLevel:), level);
78        }
79    }
80
81    /// Get the slice for this attachment.
82    ///
83    /// C++ equivalent: `NS::UInteger slice() const`
84    #[inline]
85    pub fn slice(&self) -> UInteger {
86        unsafe { msg_send_0(self.as_ptr(), sel!(slice)) }
87    }
88
89    /// Set the slice for this attachment.
90    ///
91    /// C++ equivalent: `void setSlice(NS::UInteger)`
92    #[inline]
93    pub fn set_slice(&self, slice: UInteger) {
94        unsafe {
95            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setSlice:), slice);
96        }
97    }
98
99    /// Get the depth plane for this attachment.
100    ///
101    /// C++ equivalent: `NS::UInteger depthPlane() const`
102    #[inline]
103    pub fn depth_plane(&self) -> UInteger {
104        unsafe { msg_send_0(self.as_ptr(), sel!(depthPlane)) }
105    }
106
107    /// Set the depth plane for this attachment.
108    ///
109    /// C++ equivalent: `void setDepthPlane(NS::UInteger)`
110    #[inline]
111    pub fn set_depth_plane(&self, depth_plane: UInteger) {
112        unsafe {
113            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setDepthPlane:), depth_plane);
114        }
115    }
116
117    /// Get the load action for this attachment.
118    ///
119    /// C++ equivalent: `LoadAction loadAction() const`
120    #[inline]
121    pub fn load_action(&self) -> LoadAction {
122        unsafe { msg_send_0(self.as_ptr(), sel!(loadAction)) }
123    }
124
125    /// Set the load action for this attachment.
126    ///
127    /// C++ equivalent: `void setLoadAction(LoadAction)`
128    #[inline]
129    pub fn set_load_action(&self, load_action: LoadAction) {
130        unsafe {
131            msg_send_1::<(), LoadAction>(self.as_ptr(), sel!(setLoadAction:), load_action);
132        }
133    }
134
135    /// Get the store action for this attachment.
136    ///
137    /// C++ equivalent: `StoreAction storeAction() const`
138    #[inline]
139    pub fn store_action(&self) -> StoreAction {
140        unsafe { msg_send_0(self.as_ptr(), sel!(storeAction)) }
141    }
142
143    /// Set the store action for this attachment.
144    ///
145    /// C++ equivalent: `void setStoreAction(StoreAction)`
146    #[inline]
147    pub fn set_store_action(&self, store_action: StoreAction) {
148        unsafe {
149            msg_send_1::<(), StoreAction>(self.as_ptr(), sel!(setStoreAction:), store_action);
150        }
151    }
152
153    /// Get the store action options for this attachment.
154    ///
155    /// C++ equivalent: `StoreActionOptions storeActionOptions() const`
156    #[inline]
157    pub fn store_action_options(&self) -> StoreActionOptions {
158        unsafe { msg_send_0(self.as_ptr(), sel!(storeActionOptions)) }
159    }
160
161    /// Set the store action options for this attachment.
162    ///
163    /// C++ equivalent: `void setStoreActionOptions(StoreActionOptions)`
164    #[inline]
165    pub fn set_store_action_options(&self, options: StoreActionOptions) {
166        unsafe {
167            msg_send_1::<(), StoreActionOptions>(
168                self.as_ptr(),
169                sel!(setStoreActionOptions:),
170                options,
171            );
172        }
173    }
174
175    /// Get the resolve texture for this attachment.
176    ///
177    /// C++ equivalent: `Texture* resolveTexture() const`
178    pub fn resolve_texture(&self) -> Option<Texture> {
179        unsafe {
180            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(resolveTexture));
181            if ptr.is_null() {
182                return None;
183            }
184            let _: *mut c_void = msg_send_0(ptr, sel!(retain));
185            Texture::from_raw(ptr)
186        }
187    }
188
189    /// Set the resolve texture for this attachment.
190    ///
191    /// C++ equivalent: `void setResolveTexture(const Texture*)`
192    pub fn set_resolve_texture(&self, texture: Option<&Texture>) {
193        unsafe {
194            let ptr = texture.map_or(std::ptr::null(), |t| t.as_ptr());
195            msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setResolveTexture:), ptr);
196        }
197    }
198
199    /// Get the resolve level for this attachment.
200    ///
201    /// C++ equivalent: `NS::UInteger resolveLevel() const`
202    #[inline]
203    pub fn resolve_level(&self) -> UInteger {
204        unsafe { msg_send_0(self.as_ptr(), sel!(resolveLevel)) }
205    }
206
207    /// Set the resolve level for this attachment.
208    ///
209    /// C++ equivalent: `void setResolveLevel(NS::UInteger)`
210    #[inline]
211    pub fn set_resolve_level(&self, level: UInteger) {
212        unsafe {
213            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setResolveLevel:), level);
214        }
215    }
216
217    /// Get the resolve slice for this attachment.
218    ///
219    /// C++ equivalent: `NS::UInteger resolveSlice() const`
220    #[inline]
221    pub fn resolve_slice(&self) -> UInteger {
222        unsafe { msg_send_0(self.as_ptr(), sel!(resolveSlice)) }
223    }
224
225    /// Set the resolve slice for this attachment.
226    ///
227    /// C++ equivalent: `void setResolveSlice(NS::UInteger)`
228    #[inline]
229    pub fn set_resolve_slice(&self, slice: UInteger) {
230        unsafe {
231            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setResolveSlice:), slice);
232        }
233    }
234
235    /// Get the resolve depth plane for this attachment.
236    ///
237    /// C++ equivalent: `NS::UInteger resolveDepthPlane() const`
238    #[inline]
239    pub fn resolve_depth_plane(&self) -> UInteger {
240        unsafe { msg_send_0(self.as_ptr(), sel!(resolveDepthPlane)) }
241    }
242
243    /// Set the resolve depth plane for this attachment.
244    ///
245    /// C++ equivalent: `void setResolveDepthPlane(NS::UInteger)`
246    #[inline]
247    pub fn set_resolve_depth_plane(&self, depth_plane: UInteger) {
248        unsafe {
249            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setResolveDepthPlane:), depth_plane);
250        }
251    }
252}
253
254impl Referencing for RenderPassAttachmentDescriptor {
255    #[inline]
256    fn as_ptr(&self) -> *const c_void {
257        self.0.as_ptr()
258    }
259}