Skip to main content

mtl_gpu/mtl4/acceleration_structure/
instance_descriptor.rs

1//! Descriptor for creating an instance acceleration structure.
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::{AccelerationStructureInstanceDescriptorType, MatrixLayout, TransformType};
10
11use super::BufferRange;
12
13/// Descriptor for creating an instance acceleration structure.
14///
15/// C++ equivalent: `MTL4::InstanceAccelerationStructureDescriptor`
16#[repr(transparent)]
17pub struct InstanceAccelerationStructureDescriptor(NonNull<c_void>);
18
19impl InstanceAccelerationStructureDescriptor {
20    /// Create from a raw pointer.
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    /// Create a new instance acceleration structure descriptor.
33    pub fn new() -> Option<Self> {
34        unsafe {
35            let class = mtl_sys::Class::get("MTL4InstanceAccelerationStructureDescriptor")?;
36            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
37            if ptr.is_null() {
38                return None;
39            }
40            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
41            Self::from_raw(ptr)
42        }
43    }
44
45    /// Get the instance count.
46    pub fn instance_count(&self) -> UInteger {
47        unsafe { msg_send_0(self.as_ptr(), sel!(instanceCount)) }
48    }
49
50    /// Set the instance count.
51    pub fn set_instance_count(&self, count: UInteger) {
52        unsafe {
53            let _: () = msg_send_1(self.as_ptr(), sel!(setInstanceCount:), count);
54        }
55    }
56
57    /// Get the instance descriptor buffer.
58    pub fn instance_descriptor_buffer(&self) -> BufferRange {
59        unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorBuffer)) }
60    }
61
62    /// Set the instance descriptor buffer.
63    pub fn set_instance_descriptor_buffer(&self, buffer: BufferRange) {
64        unsafe {
65            let _: () = msg_send_1(self.as_ptr(), sel!(setInstanceDescriptorBuffer:), buffer);
66        }
67    }
68
69    /// Get the instance descriptor stride.
70    pub fn instance_descriptor_stride(&self) -> UInteger {
71        unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorStride)) }
72    }
73
74    /// Set the instance descriptor stride.
75    pub fn set_instance_descriptor_stride(&self, stride: UInteger) {
76        unsafe {
77            let _: () = msg_send_1(self.as_ptr(), sel!(setInstanceDescriptorStride:), stride);
78        }
79    }
80
81    /// Get the instance descriptor type.
82    pub fn instance_descriptor_type(&self) -> AccelerationStructureInstanceDescriptorType {
83        unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorType)) }
84    }
85
86    /// Set the instance descriptor type.
87    pub fn set_instance_descriptor_type(
88        &self,
89        descriptor_type: AccelerationStructureInstanceDescriptorType,
90    ) {
91        unsafe {
92            let _: () = msg_send_1(
93                self.as_ptr(),
94                sel!(setInstanceDescriptorType:),
95                descriptor_type,
96            );
97        }
98    }
99
100    /// Get the instance transformation matrix layout.
101    pub fn instance_transformation_matrix_layout(&self) -> MatrixLayout {
102        unsafe { msg_send_0(self.as_ptr(), sel!(instanceTransformationMatrixLayout)) }
103    }
104
105    /// Set the instance transformation matrix layout.
106    pub fn set_instance_transformation_matrix_layout(&self, layout: MatrixLayout) {
107        unsafe {
108            let _: () = msg_send_1(
109                self.as_ptr(),
110                sel!(setInstanceTransformationMatrixLayout:),
111                layout,
112            );
113        }
114    }
115
116    /// Get the motion transform buffer.
117    pub fn motion_transform_buffer(&self) -> BufferRange {
118        unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformBuffer)) }
119    }
120
121    /// Set the motion transform buffer.
122    pub fn set_motion_transform_buffer(&self, buffer: BufferRange) {
123        unsafe {
124            let _: () = msg_send_1(self.as_ptr(), sel!(setMotionTransformBuffer:), buffer);
125        }
126    }
127
128    /// Get the motion transform count.
129    pub fn motion_transform_count(&self) -> UInteger {
130        unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformCount)) }
131    }
132
133    /// Set the motion transform count.
134    pub fn set_motion_transform_count(&self, count: UInteger) {
135        unsafe {
136            let _: () = msg_send_1(self.as_ptr(), sel!(setMotionTransformCount:), count);
137        }
138    }
139
140    /// Get the motion transform stride.
141    pub fn motion_transform_stride(&self) -> UInteger {
142        unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformStride)) }
143    }
144
145    /// Set the motion transform stride.
146    pub fn set_motion_transform_stride(&self, stride: UInteger) {
147        unsafe {
148            let _: () = msg_send_1(self.as_ptr(), sel!(setMotionTransformStride:), stride);
149        }
150    }
151
152    /// Get the motion transform type.
153    pub fn motion_transform_type(&self) -> TransformType {
154        unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformType)) }
155    }
156
157    /// Set the motion transform type.
158    pub fn set_motion_transform_type(&self, transform_type: TransformType) {
159        unsafe {
160            let _: () = msg_send_1(self.as_ptr(), sel!(setMotionTransformType:), transform_type);
161        }
162    }
163}
164
165impl Default for InstanceAccelerationStructureDescriptor {
166    fn default() -> Self {
167        Self::new().expect("Failed to create MTL4InstanceAccelerationStructureDescriptor")
168    }
169}
170
171impl Clone for InstanceAccelerationStructureDescriptor {
172    fn clone(&self) -> Self {
173        unsafe {
174            mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
175        }
176        Self(self.0)
177    }
178}
179
180impl Drop for InstanceAccelerationStructureDescriptor {
181    fn drop(&mut self) {
182        unsafe {
183            mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
184        }
185    }
186}
187
188impl Referencing for InstanceAccelerationStructureDescriptor {
189    #[inline]
190    fn as_ptr(&self) -> *const c_void {
191        self.0.as_ptr()
192    }
193}
194
195unsafe impl Send for InstanceAccelerationStructureDescriptor {}
196unsafe impl Sync for InstanceAccelerationStructureDescriptor {}
197
198impl std::fmt::Debug for InstanceAccelerationStructureDescriptor {
199    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
200        f.debug_struct("InstanceAccelerationStructureDescriptor")
201            .field("instance_count", &self.instance_count())
202            .finish()
203    }
204}