Skip to main content

apple_mps/
ray.rs

1use crate::ffi;
2use apple_metal::{CommandBuffer, MetalBuffer, MetalDevice};
3use core::ffi::c_void;
4use core::ptr;
5
6/// `MPSPolygonType` constants.
7pub mod polygon_type {
8    /// Wraps a `MPSPolygonType` raw value.
9    pub const TRIANGLE: usize = 0;
10    /// Wraps a `MPSPolygonType` raw value.
11    pub const QUADRILATERAL: usize = 1;
12}
13
14/// `MPSAccelerationStructureUsage` bitflags.
15pub mod acceleration_structure_usage {
16    /// Wraps a `MPSAccelerationStructureUsage` raw value.
17    pub const NONE: usize = 0;
18    /// Wraps a `MPSAccelerationStructureUsage` raw value.
19    pub const REFIT: usize = 1;
20    /// Wraps a `MPSAccelerationStructureUsage` raw value.
21    pub const FREQUENT_REBUILD: usize = 2;
22    /// Wraps a `MPSAccelerationStructureUsage` raw value.
23    pub const PREFER_GPU_BUILD: usize = 4;
24    /// Wraps a `MPSAccelerationStructureUsage` raw value.
25    pub const PREFER_CPU_BUILD: usize = 8;
26}
27
28/// `MPSAccelerationStructureStatus` constants.
29pub mod acceleration_structure_status {
30    /// Wraps a `MPSAccelerationStructureStatus` raw value.
31    pub const UNBUILT: usize = 0;
32    /// Wraps a `MPSAccelerationStructureStatus` raw value.
33    pub const BUILT: usize = 1;
34}
35
36/// `MPSIntersectionType` constants.
37pub mod intersection_type {
38    /// Wraps a `MPSIntersectionType` raw value.
39    pub const NEAREST: usize = 0;
40    /// Wraps a `MPSIntersectionType` raw value.
41    pub const ANY: usize = 1;
42}
43
44/// `MPSRayDataType` constants.
45pub mod ray_data_type {
46    /// Wraps a `MPSRayDataType` raw value.
47    pub const ORIGIN_DIRECTION: usize = 0;
48    /// Wraps a `MPSRayDataType` raw value.
49    pub const ORIGIN_MIN_DISTANCE_DIRECTION_MAX_DISTANCE: usize = 1;
50    /// Wraps a `MPSRayDataType` raw value.
51    pub const ORIGIN_MASK_DIRECTION_MAX_DISTANCE: usize = 2;
52    /// Wraps a `MPSRayDataType` raw value.
53    pub const PACKED_ORIGIN_DIRECTION: usize = 3;
54}
55
56/// `MPSIntersectionDataType` constants.
57pub mod intersection_data_type {
58    /// Wraps a `MPSIntersectionDataType` raw value.
59    pub const DISTANCE: usize = 0;
60    /// Wraps a `MPSIntersectionDataType` raw value.
61    pub const DISTANCE_PRIMITIVE_INDEX: usize = 1;
62    /// Wraps a `MPSIntersectionDataType` raw value.
63    pub const DISTANCE_PRIMITIVE_INDEX_COORDINATES: usize = 2;
64    /// Wraps a `MPSIntersectionDataType` raw value.
65    pub const DISTANCE_PRIMITIVE_INDEX_INSTANCE_INDEX: usize = 3;
66    /// Wraps a `MPSIntersectionDataType` raw value.
67    pub const DISTANCE_PRIMITIVE_INDEX_INSTANCE_INDEX_COORDINATES: usize = 4;
68    /// Wraps a `MPSIntersectionDataType` raw value.
69    pub const DISTANCE_PRIMITIVE_INDEX_BUFFER_INDEX: usize = 5;
70    /// Wraps a `MPSIntersectionDataType` raw value.
71    pub const DISTANCE_PRIMITIVE_INDEX_BUFFER_INDEX_COORDINATES: usize = 6;
72    /// Wraps a `MPSIntersectionDataType` raw value.
73    pub const DISTANCE_PRIMITIVE_INDEX_BUFFER_INDEX_INSTANCE_INDEX: usize = 7;
74    /// Wraps a `MPSIntersectionDataType` raw value.
75    pub const DISTANCE_PRIMITIVE_INDEX_BUFFER_INDEX_INSTANCE_INDEX_COORDINATES: usize = 8;
76}
77
78/// `MTLCullMode` constants.
79pub mod cull_mode {
80    /// Wraps a `MTLCullMode` raw value.
81    pub const NONE: usize = 0;
82    /// Wraps a `MTLCullMode` raw value.
83    pub const FRONT: usize = 1;
84    /// Wraps a `MTLCullMode` raw value.
85    pub const BACK: usize = 2;
86}
87
88/// `MTLWinding` constants.
89pub mod winding {
90    /// Wraps a `MTLWinding` raw value.
91    pub const CLOCKWISE: usize = 0;
92    /// Wraps a `MTLWinding` raw value.
93    pub const COUNTER_CLOCKWISE: usize = 1;
94}
95
96#[doc(hidden)]
97pub use crate::generated::ray::*;
98
99macro_rules! opaque_handle {
100    ($name:ident, $doc:expr) => {
101        #[doc = $doc]
102        pub struct $name {
103            ptr: *mut c_void,
104        }
105
106        // SAFETY: MPS handles are opaque pointers to thread-safe Swift/ObjC objects.
107        unsafe impl Send for $name {}
108        // SAFETY: MPS handles are opaque pointers to thread-safe Swift/ObjC objects.
109        unsafe impl Sync for $name {}
110
111        impl Drop for $name {
112            fn drop(&mut self) {
113                if !self.ptr.is_null() {
114                    // SAFETY: `ptr` is a +1 retained MPS object owned by this wrapper.
115                    unsafe { ffi::mps_object_release(self.ptr) };
116                    self.ptr = ptr::null_mut();
117                }
118            }
119        }
120
121        impl $name {
122            /// Returns the retained Objective-C pointer backing this wrapper.
123            #[must_use]
124            pub const fn as_ptr(&self) -> *mut c_void {
125                self.ptr
126            }
127        }
128    };
129}
130
131opaque_handle!(PolygonAccelerationStructure, "Wraps `MPSPolygonAccelerationStructure`.");
132impl PolygonAccelerationStructure {
133    /// Wraps a constructor on `MPSPolygonAccelerationStructure`.
134    #[must_use]
135    pub fn new(device: &MetalDevice) -> Option<Self> {
136        let ptr = unsafe { ffi::mps_polygon_acceleration_structure_new(device.as_ptr()) };
137        if ptr.is_null() {
138            None
139        } else {
140            Some(Self { ptr })
141        }
142    }
143
144    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
145    #[must_use]
146    pub fn polygon_type(&self) -> usize {
147        unsafe { ffi::mps_polygon_acceleration_structure_polygon_type(self.ptr) }
148    }
149
150    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
151    pub fn set_polygon_type(&self, polygon_type: usize) {
152        unsafe { ffi::mps_polygon_acceleration_structure_set_polygon_type(self.ptr, polygon_type) };
153    }
154
155    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
156    #[must_use]
157    pub fn vertex_stride(&self) -> usize {
158        unsafe { ffi::mps_polygon_acceleration_structure_vertex_stride(self.ptr) }
159    }
160
161    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
162    pub fn set_vertex_stride(&self, vertex_stride: usize) {
163        unsafe {
164            ffi::mps_polygon_acceleration_structure_set_vertex_stride(self.ptr, vertex_stride);
165        };
166    }
167
168    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
169    #[must_use]
170    pub fn index_type(&self) -> u32 {
171        unsafe { ffi::mps_polygon_acceleration_structure_index_type(self.ptr) }
172    }
173
174    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
175    pub fn set_index_type(&self, index_type: u32) {
176        unsafe { ffi::mps_polygon_acceleration_structure_set_index_type(self.ptr, index_type) };
177    }
178
179    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
180    pub fn set_vertex_buffer(&self, buffer: Option<&MetalBuffer>) {
181        let buffer_ptr = buffer.map_or(ptr::null_mut(), MetalBuffer::as_ptr);
182        unsafe { ffi::mps_polygon_acceleration_structure_set_vertex_buffer(self.ptr, buffer_ptr) };
183    }
184
185    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
186    #[must_use]
187    pub fn vertex_buffer_offset(&self) -> usize {
188        unsafe { ffi::mps_polygon_acceleration_structure_vertex_buffer_offset(self.ptr) }
189    }
190
191    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
192    pub fn set_vertex_buffer_offset(&self, offset: usize) {
193        unsafe {
194            ffi::mps_polygon_acceleration_structure_set_vertex_buffer_offset(self.ptr, offset);
195        };
196    }
197
198    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
199    pub fn set_index_buffer(&self, buffer: Option<&MetalBuffer>) {
200        let buffer_ptr = buffer.map_or(ptr::null_mut(), MetalBuffer::as_ptr);
201        unsafe { ffi::mps_polygon_acceleration_structure_set_index_buffer(self.ptr, buffer_ptr) };
202    }
203
204    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
205    #[must_use]
206    pub fn index_buffer_offset(&self) -> usize {
207        unsafe { ffi::mps_polygon_acceleration_structure_index_buffer_offset(self.ptr) }
208    }
209
210    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
211    pub fn set_index_buffer_offset(&self, offset: usize) {
212        unsafe {
213            ffi::mps_polygon_acceleration_structure_set_index_buffer_offset(self.ptr, offset);
214        };
215    }
216
217    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
218    #[must_use]
219    pub fn polygon_count(&self) -> usize {
220        unsafe { ffi::mps_polygon_acceleration_structure_polygon_count(self.ptr) }
221    }
222
223    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
224    pub fn set_polygon_count(&self, count: usize) {
225        unsafe { ffi::mps_polygon_acceleration_structure_set_polygon_count(self.ptr, count) };
226    }
227
228    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
229    #[must_use]
230    pub fn usage(&self) -> usize {
231        unsafe { ffi::mps_polygon_acceleration_structure_usage(self.ptr) }
232    }
233
234    /// Wraps the corresponding `MPSPolygonAccelerationStructure` setter.
235    pub fn set_usage(&self, usage: usize) {
236        unsafe { ffi::mps_polygon_acceleration_structure_set_usage(self.ptr, usage) };
237    }
238
239    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
240    #[must_use]
241    pub fn status(&self) -> usize {
242        unsafe { ffi::mps_polygon_acceleration_structure_status(self.ptr) }
243    }
244
245    /// Wraps the corresponding `MPSPolygonAccelerationStructure` method.
246    pub fn rebuild(&self) {
247        unsafe { ffi::mps_polygon_acceleration_structure_rebuild(self.ptr) };
248    }
249
250    /// Wraps the corresponding `MPSPolygonAccelerationStructure` encode entry point.
251    pub fn encode_refit(&self, command_buffer: &CommandBuffer) {
252        unsafe {
253            ffi::mps_polygon_acceleration_structure_encode_refit(self.ptr, command_buffer.as_ptr());
254        };
255    }
256}
257
258opaque_handle!(RayIntersector, "Wraps `MPSRayIntersector`.");
259impl RayIntersector {
260    /// Wraps a constructor on `MPSRayIntersector`.
261    #[must_use]
262    pub fn new(device: &MetalDevice) -> Option<Self> {
263        let ptr = unsafe { ffi::mps_ray_intersector_new(device.as_ptr()) };
264        if ptr.is_null() {
265            None
266        } else {
267            Some(Self { ptr })
268        }
269    }
270
271    /// Wraps the corresponding `MPSRayIntersector` method.
272    #[must_use]
273    pub fn cull_mode(&self) -> usize {
274        unsafe { ffi::mps_ray_intersector_cull_mode(self.ptr) }
275    }
276
277    /// Wraps the corresponding `MPSRayIntersector` setter.
278    pub fn set_cull_mode(&self, cull_mode: usize) {
279        unsafe { ffi::mps_ray_intersector_set_cull_mode(self.ptr, cull_mode) };
280    }
281
282    /// Wraps the corresponding `MPSRayIntersector` method.
283    #[must_use]
284    pub fn front_facing_winding(&self) -> usize {
285        unsafe { ffi::mps_ray_intersector_front_facing_winding(self.ptr) }
286    }
287
288    /// Wraps the corresponding `MPSRayIntersector` setter.
289    pub fn set_front_facing_winding(&self, winding: usize) {
290        unsafe { ffi::mps_ray_intersector_set_front_facing_winding(self.ptr, winding) };
291    }
292
293    /// Wraps the corresponding `MPSRayIntersector` method.
294    #[must_use]
295    pub fn ray_stride(&self) -> usize {
296        unsafe { ffi::mps_ray_intersector_ray_stride(self.ptr) }
297    }
298
299    /// Wraps the corresponding `MPSRayIntersector` setter.
300    pub fn set_ray_stride(&self, stride: usize) {
301        unsafe { ffi::mps_ray_intersector_set_ray_stride(self.ptr, stride) };
302    }
303
304    /// Wraps the corresponding `MPSRayIntersector` method.
305    #[must_use]
306    pub fn intersection_stride(&self) -> usize {
307        unsafe { ffi::mps_ray_intersector_intersection_stride(self.ptr) }
308    }
309
310    /// Wraps the corresponding `MPSRayIntersector` setter.
311    pub fn set_intersection_stride(&self, stride: usize) {
312        unsafe { ffi::mps_ray_intersector_set_intersection_stride(self.ptr, stride) };
313    }
314
315    /// Wraps the corresponding `MPSRayIntersector` method.
316    #[must_use]
317    pub fn ray_data_type(&self) -> usize {
318        unsafe { ffi::mps_ray_intersector_ray_data_type(self.ptr) }
319    }
320
321    /// Wraps the corresponding `MPSRayIntersector` setter.
322    pub fn set_ray_data_type(&self, data_type: usize) {
323        unsafe { ffi::mps_ray_intersector_set_ray_data_type(self.ptr, data_type) };
324    }
325
326    /// Wraps the corresponding `MPSRayIntersector` method.
327    #[must_use]
328    pub fn intersection_data_type(&self) -> usize {
329        unsafe { ffi::mps_ray_intersector_intersection_data_type(self.ptr) }
330    }
331
332    /// Wraps the corresponding `MPSRayIntersector` setter.
333    pub fn set_intersection_data_type(&self, data_type: usize) {
334        unsafe { ffi::mps_ray_intersector_set_intersection_data_type(self.ptr, data_type) };
335    }
336
337    /// Wraps the corresponding `MPSRayIntersector` method.
338    #[must_use]
339    pub fn recommended_minimum_ray_batch_size(&self, ray_count: usize) -> usize {
340        unsafe { ffi::mps_ray_intersector_recommended_minimum_ray_batch_size(self.ptr, ray_count) }
341    }
342
343    /// Wraps the corresponding `MPSRayIntersector` encode entry point.
344    #[allow(clippy::too_many_arguments)]
345    pub fn encode_intersection(
346        &self,
347        command_buffer: &CommandBuffer,
348        intersection_type: usize,
349        ray_buffer: &MetalBuffer,
350        ray_buffer_offset: usize,
351        intersection_buffer: &MetalBuffer,
352        intersection_buffer_offset: usize,
353        ray_count: usize,
354        acceleration_structure: &PolygonAccelerationStructure,
355    ) {
356        unsafe {
357            ffi::mps_ray_intersector_encode_intersection(
358                self.ptr,
359                command_buffer.as_ptr(),
360                intersection_type,
361                ray_buffer.as_ptr(),
362                ray_buffer_offset,
363                intersection_buffer.as_ptr(),
364                intersection_buffer_offset,
365                ray_count,
366                acceleration_structure.as_ptr(),
367            );
368        };
369    }
370}
371
372opaque_handle!(SVGF, "Wraps `MPSSVGF`.");
373impl SVGF {
374    /// Wraps a constructor on `MPSSVGF`.
375    #[must_use]
376    pub fn new(device: &MetalDevice) -> Option<Self> {
377        let ptr = unsafe { ffi::mps_svgf_new(device.as_ptr()) };
378        if ptr.is_null() {
379            None
380        } else {
381            Some(Self { ptr })
382        }
383    }
384
385    /// Wraps the corresponding `MPSSVGF` method.
386    #[must_use]
387    pub fn depth_weight(&self) -> f32 {
388        unsafe { ffi::mps_svgf_depth_weight(self.ptr) }
389    }
390
391    /// Wraps the corresponding `MPSSVGF` setter.
392    pub fn set_depth_weight(&self, value: f32) {
393        unsafe { ffi::mps_svgf_set_depth_weight(self.ptr, value) };
394    }
395
396    /// Wraps the corresponding `MPSSVGF` method.
397    #[must_use]
398    pub fn normal_weight(&self) -> f32 {
399        unsafe { ffi::mps_svgf_normal_weight(self.ptr) }
400    }
401
402    /// Wraps the corresponding `MPSSVGF` setter.
403    pub fn set_normal_weight(&self, value: f32) {
404        unsafe { ffi::mps_svgf_set_normal_weight(self.ptr, value) };
405    }
406
407    /// Wraps the corresponding `MPSSVGF` method.
408    #[must_use]
409    pub fn luminance_weight(&self) -> f32 {
410        unsafe { ffi::mps_svgf_luminance_weight(self.ptr) }
411    }
412
413    /// Wraps the corresponding `MPSSVGF` setter.
414    pub fn set_luminance_weight(&self, value: f32) {
415        unsafe { ffi::mps_svgf_set_luminance_weight(self.ptr, value) };
416    }
417
418    /// Wraps the corresponding `MPSSVGF` method.
419    #[must_use]
420    pub fn channel_count(&self) -> usize {
421        unsafe { ffi::mps_svgf_channel_count(self.ptr) }
422    }
423
424    /// Wraps the corresponding `MPSSVGF` setter.
425    pub fn set_channel_count(&self, value: usize) {
426        unsafe { ffi::mps_svgf_set_channel_count(self.ptr, value) };
427    }
428
429    /// Wraps the corresponding `MPSSVGF` method.
430    #[must_use]
431    pub fn channel_count2(&self) -> usize {
432        unsafe { ffi::mps_svgf_channel_count2(self.ptr) }
433    }
434
435    /// Wraps the corresponding `MPSSVGF` setter.
436    pub fn set_channel_count2(&self, value: usize) {
437        unsafe { ffi::mps_svgf_set_channel_count2(self.ptr, value) };
438    }
439}