Skip to main content

mtl_gpu/mtl4/acceleration_structure/
indirect_instance_descriptor.rs

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