Skip to main content

mtl_gpu/enums/
acceleration.rs

1//! Acceleration structure enumerations.
2//!
3//! Corresponds to `Metal/MTLAccelerationStructure.hpp`.
4
5use mtl_foundation::{Integer, UInteger};
6
7/// Matrix layout for acceleration structure transforms.
8///
9/// C++ equivalent: `MTL::MatrixLayout`
10#[repr(transparent)]
11#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
12pub struct MatrixLayout(pub Integer);
13
14impl MatrixLayout {
15    pub const COLUMN_MAJOR: Self = Self(0);
16    pub const ROW_MAJOR: Self = Self(1);
17}
18
19/// Motion border mode for motion blur.
20///
21/// C++ equivalent: `MTL::MotionBorderMode`
22///
23/// Note: Uses u32, not UInteger.
24#[repr(transparent)]
25#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
26pub struct MotionBorderMode(pub u32);
27
28impl MotionBorderMode {
29    pub const CLAMP: Self = Self(0);
30    pub const VANISH: Self = Self(1);
31}
32
33/// Curve type for curve geometry.
34///
35/// C++ equivalent: `MTL::CurveType`
36#[repr(transparent)]
37#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
38pub struct CurveType(pub Integer);
39
40impl CurveType {
41    pub const ROUND: Self = Self(0);
42    pub const FLAT: Self = Self(1);
43}
44
45/// Curve basis for curve geometry.
46///
47/// C++ equivalent: `MTL::CurveBasis`
48#[repr(transparent)]
49#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
50pub struct CurveBasis(pub Integer);
51
52impl CurveBasis {
53    pub const B_SPLINE: Self = Self(0);
54    pub const CATMULL_ROM: Self = Self(1);
55    pub const LINEAR: Self = Self(2);
56    pub const BEZIER: Self = Self(3);
57}
58
59/// Curve end caps style.
60///
61/// C++ equivalent: `MTL::CurveEndCaps`
62#[repr(transparent)]
63#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
64pub struct CurveEndCaps(pub Integer);
65
66impl CurveEndCaps {
67    pub const NONE: Self = Self(0);
68    pub const DISK: Self = Self(1);
69    pub const SPHERE: Self = Self(2);
70}
71
72/// Acceleration structure instance descriptor type.
73///
74/// C++ equivalent: `MTL::AccelerationStructureInstanceDescriptorType`
75#[repr(transparent)]
76#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
77pub struct AccelerationStructureInstanceDescriptorType(pub UInteger);
78
79impl AccelerationStructureInstanceDescriptorType {
80    pub const DEFAULT: Self = Self(0);
81    pub const USER_ID: Self = Self(1);
82    pub const MOTION: Self = Self(2);
83    pub const INDIRECT: Self = Self(3);
84    pub const INDIRECT_MOTION: Self = Self(4);
85}
86
87/// Transform type for acceleration structures.
88///
89/// C++ equivalent: `MTL::TransformType`
90#[repr(transparent)]
91#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
92pub struct TransformType(pub Integer);
93
94impl TransformType {
95    pub const PACKED_FLOAT4X3: Self = Self(0);
96    pub const COMPONENT: Self = Self(1);
97}
98
99/// Acceleration structure refit options (bitflags).
100///
101/// C++ equivalent: `MTL::AccelerationStructureRefitOptions`
102#[repr(transparent)]
103#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
104pub struct AccelerationStructureRefitOptions(pub UInteger);
105
106impl AccelerationStructureRefitOptions {
107    pub const NONE: Self = Self(0);
108    pub const VERTEX_DATA: Self = Self(1);
109    pub const PER_PRIMITIVE_DATA: Self = Self(1 << 1);
110
111    /// Returns the raw bits.
112    #[inline]
113    pub const fn bits(&self) -> UInteger {
114        self.0
115    }
116
117    /// Creates from raw bits.
118    #[inline]
119    pub const fn from_bits(bits: UInteger) -> Self {
120        Self(bits)
121    }
122
123    /// Check if empty.
124    #[inline]
125    pub const fn is_empty(&self) -> bool {
126        self.0 == 0
127    }
128
129    /// Check if contains all flags in other.
130    #[inline]
131    pub const fn contains(&self, other: Self) -> bool {
132        (self.0 & other.0) == other.0
133    }
134}
135
136impl std::ops::BitOr for AccelerationStructureRefitOptions {
137    type Output = Self;
138    #[inline]
139    fn bitor(self, rhs: Self) -> Self {
140        Self(self.0 | rhs.0)
141    }
142}
143
144impl std::ops::BitAnd for AccelerationStructureRefitOptions {
145    type Output = Self;
146    #[inline]
147    fn bitand(self, rhs: Self) -> Self {
148        Self(self.0 & rhs.0)
149    }
150}
151
152impl std::ops::BitOrAssign for AccelerationStructureRefitOptions {
153    #[inline]
154    fn bitor_assign(&mut self, rhs: Self) {
155        self.0 |= rhs.0;
156    }
157}
158
159/// Acceleration structure usage options (bitflags).
160///
161/// C++ equivalent: `MTL::AccelerationStructureUsage`
162#[repr(transparent)]
163#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
164pub struct AccelerationStructureUsage(pub UInteger);
165
166impl AccelerationStructureUsage {
167    pub const NONE: Self = Self(0);
168    pub const REFIT: Self = Self(1);
169    pub const PREFER_FAST_BUILD: Self = Self(1 << 1);
170    pub const EXTENDED_LIMITS: Self = Self(1 << 2);
171    pub const PREFER_FAST_INTERSECTION: Self = Self(1 << 4);
172    pub const MINIMIZE_MEMORY: Self = Self(1 << 5);
173
174    /// Returns the raw bits.
175    #[inline]
176    pub const fn bits(&self) -> UInteger {
177        self.0
178    }
179
180    /// Creates from raw bits.
181    #[inline]
182    pub const fn from_bits(bits: UInteger) -> Self {
183        Self(bits)
184    }
185
186    /// Check if empty.
187    #[inline]
188    pub const fn is_empty(&self) -> bool {
189        self.0 == 0
190    }
191
192    /// Check if contains all flags in other.
193    #[inline]
194    pub const fn contains(&self, other: Self) -> bool {
195        (self.0 & other.0) == other.0
196    }
197}
198
199impl std::ops::BitOr for AccelerationStructureUsage {
200    type Output = Self;
201    #[inline]
202    fn bitor(self, rhs: Self) -> Self {
203        Self(self.0 | rhs.0)
204    }
205}
206
207impl std::ops::BitAnd for AccelerationStructureUsage {
208    type Output = Self;
209    #[inline]
210    fn bitand(self, rhs: Self) -> Self {
211        Self(self.0 & rhs.0)
212    }
213}
214
215impl std::ops::BitOrAssign for AccelerationStructureUsage {
216    #[inline]
217    fn bitor_assign(&mut self, rhs: Self) {
218        self.0 |= rhs.0;
219    }
220}
221
222/// Acceleration structure instance options (bitflags).
223///
224/// C++ equivalent: `MTL::AccelerationStructureInstanceOptions`
225///
226/// Note: Uses u32, not UInteger.
227#[repr(transparent)]
228#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
229pub struct AccelerationStructureInstanceOptions(pub u32);
230
231impl AccelerationStructureInstanceOptions {
232    pub const NONE: Self = Self(0);
233    pub const DISABLE_TRIANGLE_CULLING: Self = Self(1);
234    pub const TRIANGLE_FRONT_FACING_WINDING_COUNTER_CLOCKWISE: Self = Self(1 << 1);
235    pub const OPAQUE: Self = Self(1 << 2);
236    pub const NON_OPAQUE: Self = Self(1 << 3);
237
238    /// Returns the raw bits.
239    #[inline]
240    pub const fn bits(&self) -> u32 {
241        self.0
242    }
243
244    /// Creates from raw bits.
245    #[inline]
246    pub const fn from_bits(bits: u32) -> Self {
247        Self(bits)
248    }
249
250    /// Check if empty.
251    #[inline]
252    pub const fn is_empty(&self) -> bool {
253        self.0 == 0
254    }
255
256    /// Check if contains all flags in other.
257    #[inline]
258    pub const fn contains(&self, other: Self) -> bool {
259        (self.0 & other.0) == other.0
260    }
261}
262
263impl std::ops::BitOr for AccelerationStructureInstanceOptions {
264    type Output = Self;
265    #[inline]
266    fn bitor(self, rhs: Self) -> Self {
267        Self(self.0 | rhs.0)
268    }
269}
270
271impl std::ops::BitAnd for AccelerationStructureInstanceOptions {
272    type Output = Self;
273    #[inline]
274    fn bitand(self, rhs: Self) -> Self {
275        Self(self.0 & rhs.0)
276    }
277}
278
279impl std::ops::BitOrAssign for AccelerationStructureInstanceOptions {
280    #[inline]
281    fn bitor_assign(&mut self, rhs: Self) {
282        self.0 |= rhs.0;
283    }
284}
285
286/// Intersection function signature options (bitflags).
287///
288/// C++ equivalent: `MTL::IntersectionFunctionSignature`
289#[repr(transparent)]
290#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
291pub struct IntersectionFunctionSignature(pub UInteger);
292
293impl IntersectionFunctionSignature {
294    pub const NONE: Self = Self(0);
295    pub const INSTANCING: Self = Self(1);
296    pub const TRIANGLE_DATA: Self = Self(1 << 1);
297    pub const WORLD_SPACE_DATA: Self = Self(1 << 2);
298    pub const INSTANCE_MOTION: Self = Self(1 << 3);
299    pub const PRIMITIVE_MOTION: Self = Self(1 << 4);
300    pub const EXTENDED_LIMITS: Self = Self(1 << 5);
301    pub const MAX_LEVELS: Self = Self(1 << 6);
302    pub const CURVE_DATA: Self = Self(1 << 7);
303    pub const INTERSECTION_FUNCTION_BUFFER: Self = Self(1 << 8);
304    pub const USER_DATA: Self = Self(1 << 9);
305
306    /// Returns the raw bits.
307    #[inline]
308    pub const fn bits(&self) -> UInteger {
309        self.0
310    }
311
312    /// Creates from raw bits.
313    #[inline]
314    pub const fn from_bits(bits: UInteger) -> Self {
315        Self(bits)
316    }
317
318    /// Check if empty.
319    #[inline]
320    pub const fn is_empty(&self) -> bool {
321        self.0 == 0
322    }
323
324    /// Check if contains all flags in other.
325    #[inline]
326    pub const fn contains(&self, other: Self) -> bool {
327        (self.0 & other.0) == other.0
328    }
329}
330
331impl std::ops::BitOr for IntersectionFunctionSignature {
332    type Output = Self;
333    #[inline]
334    fn bitor(self, rhs: Self) -> Self {
335        Self(self.0 | rhs.0)
336    }
337}
338
339impl std::ops::BitAnd for IntersectionFunctionSignature {
340    type Output = Self;
341    #[inline]
342    fn bitand(self, rhs: Self) -> Self {
343        Self(self.0 & rhs.0)
344    }
345}
346
347impl std::ops::BitOrAssign for IntersectionFunctionSignature {
348    #[inline]
349    fn bitor_assign(&mut self, rhs: Self) {
350        self.0 |= rhs.0;
351    }
352}
353
354#[cfg(test)]
355mod tests {
356    use super::*;
357
358    #[test]
359    fn test_matrix_layout_values() {
360        assert_eq!(MatrixLayout::COLUMN_MAJOR.0, 0);
361        assert_eq!(MatrixLayout::ROW_MAJOR.0, 1);
362    }
363
364    #[test]
365    fn test_motion_border_mode_values() {
366        assert_eq!(MotionBorderMode::CLAMP.0, 0);
367        assert_eq!(MotionBorderMode::VANISH.0, 1);
368    }
369
370    #[test]
371    fn test_curve_basis_values() {
372        assert_eq!(CurveBasis::B_SPLINE.0, 0);
373        assert_eq!(CurveBasis::BEZIER.0, 3);
374    }
375
376    #[test]
377    fn test_acceleration_structure_usage_bitor() {
378        let usage =
379            AccelerationStructureUsage::REFIT | AccelerationStructureUsage::PREFER_FAST_BUILD;
380        assert!(usage.contains(AccelerationStructureUsage::REFIT));
381        assert!(usage.contains(AccelerationStructureUsage::PREFER_FAST_BUILD));
382    }
383
384    #[test]
385    fn test_acceleration_structure_instance_options_bitor() {
386        let opts = AccelerationStructureInstanceOptions::DISABLE_TRIANGLE_CULLING
387            | AccelerationStructureInstanceOptions::OPAQUE;
388        assert!(opts.contains(AccelerationStructureInstanceOptions::DISABLE_TRIANGLE_CULLING));
389        assert!(opts.contains(AccelerationStructureInstanceOptions::OPAQUE));
390    }
391
392    #[test]
393    fn test_motion_border_mode_size() {
394        assert_eq!(std::mem::size_of::<MotionBorderMode>(), 4);
395    }
396
397    #[test]
398    fn test_instance_options_size() {
399        assert_eq!(
400            std::mem::size_of::<AccelerationStructureInstanceOptions>(),
401            4
402        );
403    }
404}