Skip to main content

mtl_gpu/acceleration/
descriptors.rs

1//! Acceleration structure descriptors.
2//!
3//! Contains base `AccelerationStructureDescriptor` and `PrimitiveAccelerationStructureDescriptor`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::{msg_send_0, msg_send_1, sel};
10
11use crate::enums::{AccelerationStructureUsage, MotionBorderMode};
12
13pub struct AccelerationStructureDescriptor(pub(crate) NonNull<c_void>);
14
15impl AccelerationStructureDescriptor {
16    /// Create an AccelerationStructureDescriptor from a raw pointer.
17    ///
18    /// # Safety
19    ///
20    /// The pointer must be a valid Metal acceleration structure descriptor object.
21    #[inline]
22    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
23        NonNull::new(ptr).map(Self)
24    }
25
26    /// Get the raw pointer.
27    #[inline]
28    pub fn as_raw(&self) -> *mut c_void {
29        self.0.as_ptr()
30    }
31
32    /// Get the usage flags.
33    ///
34    /// C++ equivalent: `AccelerationStructureUsage usage() const`
35    #[inline]
36    pub fn usage(&self) -> AccelerationStructureUsage {
37        unsafe { msg_send_0(self.as_ptr(), sel!(usage)) }
38    }
39
40    /// Set the usage flags.
41    ///
42    /// C++ equivalent: `void setUsage(AccelerationStructureUsage)`
43    #[inline]
44    pub fn set_usage(&self, usage: AccelerationStructureUsage) {
45        unsafe {
46            msg_send_1::<(), AccelerationStructureUsage>(self.as_ptr(), sel!(setUsage:), usage);
47        }
48    }
49}
50
51impl Clone for AccelerationStructureDescriptor {
52    fn clone(&self) -> Self {
53        unsafe {
54            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
55            Self::from_raw(ptr).expect("failed to copy acceleration structure descriptor")
56        }
57    }
58}
59
60impl Drop for AccelerationStructureDescriptor {
61    fn drop(&mut self) {
62        unsafe {
63            msg_send_0::<()>(self.as_ptr(), sel!(release));
64        }
65    }
66}
67
68impl Referencing for AccelerationStructureDescriptor {
69    #[inline]
70    fn as_ptr(&self) -> *const c_void {
71        self.0.as_ptr()
72    }
73}
74
75unsafe impl Send for AccelerationStructureDescriptor {}
76unsafe impl Sync for AccelerationStructureDescriptor {}
77
78// ============================================================================
79// PrimitiveAccelerationStructureDescriptor
80// ============================================================================
81
82/// Descriptor for primitive (bottom-level) acceleration structures.
83///
84/// C++ equivalent: `MTL::PrimitiveAccelerationStructureDescriptor`
85#[repr(transparent)]
86pub struct PrimitiveAccelerationStructureDescriptor(pub(crate) NonNull<c_void>);
87
88impl PrimitiveAccelerationStructureDescriptor {
89    /// Create a new primitive acceleration structure descriptor.
90    ///
91    /// C++ equivalent: `static PrimitiveAccelerationStructureDescriptor* alloc()->init()`
92    pub fn new() -> Option<Self> {
93        unsafe {
94            let class = mtl_sys::Class::get("MTLPrimitiveAccelerationStructureDescriptor")?;
95            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
96            if ptr.is_null() {
97                return None;
98            }
99            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
100            Self::from_raw(ptr)
101        }
102    }
103
104    /// Create from a raw pointer.
105    ///
106    /// # Safety
107    ///
108    /// The pointer must be a valid Metal primitive acceleration structure descriptor.
109    #[inline]
110    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
111        NonNull::new(ptr).map(Self)
112    }
113
114    /// Get the raw pointer.
115    #[inline]
116    pub fn as_raw(&self) -> *mut c_void {
117        self.0.as_ptr()
118    }
119
120    /// Get the usage flags.
121    ///
122    /// C++ equivalent: `AccelerationStructureUsage usage() const`
123    #[inline]
124    pub fn usage(&self) -> AccelerationStructureUsage {
125        unsafe { msg_send_0(self.as_ptr(), sel!(usage)) }
126    }
127
128    /// Set the usage flags.
129    ///
130    /// C++ equivalent: `void setUsage(AccelerationStructureUsage)`
131    #[inline]
132    pub fn set_usage(&self, usage: AccelerationStructureUsage) {
133        unsafe {
134            msg_send_1::<(), AccelerationStructureUsage>(self.as_ptr(), sel!(setUsage:), usage);
135        }
136    }
137
138    /// Get the motion start border mode.
139    ///
140    /// C++ equivalent: `MotionBorderMode motionStartBorderMode() const`
141    #[inline]
142    pub fn motion_start_border_mode(&self) -> MotionBorderMode {
143        unsafe { msg_send_0(self.as_ptr(), sel!(motionStartBorderMode)) }
144    }
145
146    /// Set the motion start border mode.
147    ///
148    /// C++ equivalent: `void setMotionStartBorderMode(MotionBorderMode)`
149    #[inline]
150    pub fn set_motion_start_border_mode(&self, mode: MotionBorderMode) {
151        unsafe {
152            msg_send_1::<(), MotionBorderMode>(
153                self.as_ptr(),
154                sel!(setMotionStartBorderMode:),
155                mode,
156            );
157        }
158    }
159
160    /// Get the motion end border mode.
161    ///
162    /// C++ equivalent: `MotionBorderMode motionEndBorderMode() const`
163    #[inline]
164    pub fn motion_end_border_mode(&self) -> MotionBorderMode {
165        unsafe { msg_send_0(self.as_ptr(), sel!(motionEndBorderMode)) }
166    }
167
168    /// Set the motion end border mode.
169    ///
170    /// C++ equivalent: `void setMotionEndBorderMode(MotionBorderMode)`
171    #[inline]
172    pub fn set_motion_end_border_mode(&self, mode: MotionBorderMode) {
173        unsafe {
174            msg_send_1::<(), MotionBorderMode>(self.as_ptr(), sel!(setMotionEndBorderMode:), mode);
175        }
176    }
177
178    /// Get the motion start time.
179    ///
180    /// C++ equivalent: `float motionStartTime() const`
181    #[inline]
182    pub fn motion_start_time(&self) -> f32 {
183        unsafe { msg_send_0(self.as_ptr(), sel!(motionStartTime)) }
184    }
185
186    /// Set the motion start time.
187    ///
188    /// C++ equivalent: `void setMotionStartTime(float)`
189    #[inline]
190    pub fn set_motion_start_time(&self, time: f32) {
191        unsafe {
192            msg_send_1::<(), f32>(self.as_ptr(), sel!(setMotionStartTime:), time);
193        }
194    }
195
196    /// Get the motion end time.
197    ///
198    /// C++ equivalent: `float motionEndTime() const`
199    #[inline]
200    pub fn motion_end_time(&self) -> f32 {
201        unsafe { msg_send_0(self.as_ptr(), sel!(motionEndTime)) }
202    }
203
204    /// Set the motion end time.
205    ///
206    /// C++ equivalent: `void setMotionEndTime(float)`
207    #[inline]
208    pub fn set_motion_end_time(&self, time: f32) {
209        unsafe {
210            msg_send_1::<(), f32>(self.as_ptr(), sel!(setMotionEndTime:), time);
211        }
212    }
213
214    /// Get the motion keyframe count.
215    ///
216    /// C++ equivalent: `NS::UInteger motionKeyframeCount() const`
217    #[inline]
218    pub fn motion_keyframe_count(&self) -> UInteger {
219        unsafe { msg_send_0(self.as_ptr(), sel!(motionKeyframeCount)) }
220    }
221
222    /// Set the motion keyframe count.
223    ///
224    /// C++ equivalent: `void setMotionKeyframeCount(NS::UInteger)`
225    #[inline]
226    pub fn set_motion_keyframe_count(&self, count: UInteger) {
227        unsafe {
228            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setMotionKeyframeCount:), count);
229        }
230    }
231
232    /// Get the geometry descriptors as a raw NS::Array pointer.
233    ///
234    /// C++ equivalent: `NS::Array* geometryDescriptors() const`
235    ///
236    /// # Safety
237    ///
238    /// The returned pointer is an NS::Array containing geometry descriptors.
239    /// The caller must manage the memory appropriately.
240    #[inline]
241    pub fn geometry_descriptors_ptr(&self) -> *const c_void {
242        unsafe { msg_send_0(self.as_ptr(), sel!(geometryDescriptors)) }
243    }
244
245    /// Set the geometry descriptors from a raw NS::Array pointer.
246    ///
247    /// C++ equivalent: `void setGeometryDescriptors(const NS::Array*)`
248    ///
249    /// # Safety
250    ///
251    /// The geometry_descriptors pointer must be a valid NS::Array or null.
252    pub unsafe fn set_geometry_descriptors_ptr(&self, geometry_descriptors: *const c_void) {
253        unsafe {
254            msg_send_1::<(), *const c_void>(
255                self.as_ptr(),
256                sel!(setGeometryDescriptors:),
257                geometry_descriptors,
258            );
259        }
260    }
261}
262
263impl Default for PrimitiveAccelerationStructureDescriptor {
264    fn default() -> Self {
265        Self::new().expect("failed to create primitive acceleration structure descriptor")
266    }
267}
268
269impl Clone for PrimitiveAccelerationStructureDescriptor {
270    fn clone(&self) -> Self {
271        unsafe {
272            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
273            Self::from_raw(ptr).expect("failed to copy descriptor")
274        }
275    }
276}
277
278impl Drop for PrimitiveAccelerationStructureDescriptor {
279    fn drop(&mut self) {
280        unsafe {
281            msg_send_0::<()>(self.as_ptr(), sel!(release));
282        }
283    }
284}
285
286impl Referencing for PrimitiveAccelerationStructureDescriptor {
287    #[inline]
288    fn as_ptr(&self) -> *const c_void {
289        self.0.as_ptr()
290    }
291}
292
293unsafe impl Send for PrimitiveAccelerationStructureDescriptor {}
294unsafe impl Sync for PrimitiveAccelerationStructureDescriptor {}