1use std::ffi::c_void;
7use std::ptr::NonNull;
8
9use mtl_foundation::{Referencing, UInteger};
10use mtl_sys::{msg_send_0, msg_send_1, sel};
11
12use crate::Buffer;
13use crate::enums::{
14 AccelerationStructureInstanceDescriptorType, AccelerationStructureUsage, MatrixLayout,
15 TransformType,
16};
17
18pub struct InstanceAccelerationStructureDescriptor(pub(crate) NonNull<c_void>);
19
20impl InstanceAccelerationStructureDescriptor {
21 pub fn new() -> Option<Self> {
25 unsafe {
26 let class = mtl_sys::Class::get("MTLInstanceAccelerationStructureDescriptor")?;
27 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
28 if ptr.is_null() {
29 return None;
30 }
31 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
32 Self::from_raw(ptr)
33 }
34 }
35
36 #[inline]
42 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
43 NonNull::new(ptr).map(Self)
44 }
45
46 #[inline]
48 pub fn as_raw(&self) -> *mut c_void {
49 self.0.as_ptr()
50 }
51
52 #[inline]
56 pub fn usage(&self) -> AccelerationStructureUsage {
57 unsafe { msg_send_0(self.as_ptr(), sel!(usage)) }
58 }
59
60 #[inline]
64 pub fn set_usage(&self, usage: AccelerationStructureUsage) {
65 unsafe {
66 msg_send_1::<(), AccelerationStructureUsage>(self.as_ptr(), sel!(setUsage:), usage);
67 }
68 }
69
70 #[inline]
74 pub fn instance_count(&self) -> UInteger {
75 unsafe { msg_send_0(self.as_ptr(), sel!(instanceCount)) }
76 }
77
78 #[inline]
82 pub fn set_instance_count(&self, count: UInteger) {
83 unsafe {
84 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setInstanceCount:), count);
85 }
86 }
87
88 pub fn instance_descriptor_buffer(&self) -> Option<Buffer> {
92 unsafe {
93 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(instanceDescriptorBuffer));
94 if ptr.is_null() {
95 return None;
96 }
97 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
98 Buffer::from_raw(ptr)
99 }
100 }
101
102 pub fn set_instance_descriptor_buffer(&self, buffer: Option<&Buffer>) {
106 unsafe {
107 msg_send_1::<(), *const c_void>(
108 self.as_ptr(),
109 sel!(setInstanceDescriptorBuffer:),
110 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
111 );
112 }
113 }
114
115 #[inline]
119 pub fn instance_descriptor_buffer_offset(&self) -> UInteger {
120 unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorBufferOffset)) }
121 }
122
123 #[inline]
127 pub fn set_instance_descriptor_buffer_offset(&self, offset: UInteger) {
128 unsafe {
129 msg_send_1::<(), UInteger>(
130 self.as_ptr(),
131 sel!(setInstanceDescriptorBufferOffset:),
132 offset,
133 );
134 }
135 }
136
137 #[inline]
141 pub fn instance_descriptor_stride(&self) -> UInteger {
142 unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorStride)) }
143 }
144
145 #[inline]
149 pub fn set_instance_descriptor_stride(&self, stride: UInteger) {
150 unsafe {
151 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setInstanceDescriptorStride:), stride);
152 }
153 }
154
155 #[inline]
159 pub fn instance_descriptor_type(&self) -> AccelerationStructureInstanceDescriptorType {
160 unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorType)) }
161 }
162
163 #[inline]
167 pub fn set_instance_descriptor_type(
168 &self,
169 descriptor_type: AccelerationStructureInstanceDescriptorType,
170 ) {
171 unsafe {
172 msg_send_1::<(), AccelerationStructureInstanceDescriptorType>(
173 self.as_ptr(),
174 sel!(setInstanceDescriptorType:),
175 descriptor_type,
176 );
177 }
178 }
179
180 #[inline]
184 pub fn instance_transformation_matrix_layout(&self) -> MatrixLayout {
185 unsafe { msg_send_0(self.as_ptr(), sel!(instanceTransformationMatrixLayout)) }
186 }
187
188 #[inline]
192 pub fn set_instance_transformation_matrix_layout(&self, layout: MatrixLayout) {
193 unsafe {
194 msg_send_1::<(), MatrixLayout>(
195 self.as_ptr(),
196 sel!(setInstanceTransformationMatrixLayout:),
197 layout,
198 );
199 }
200 }
201
202 pub fn motion_transform_buffer(&self) -> Option<Buffer> {
206 unsafe {
207 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(motionTransformBuffer));
208 if ptr.is_null() {
209 return None;
210 }
211 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
212 Buffer::from_raw(ptr)
213 }
214 }
215
216 pub fn set_motion_transform_buffer(&self, buffer: Option<&Buffer>) {
220 unsafe {
221 msg_send_1::<(), *const c_void>(
222 self.as_ptr(),
223 sel!(setMotionTransformBuffer:),
224 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
225 );
226 }
227 }
228
229 #[inline]
233 pub fn motion_transform_buffer_offset(&self) -> UInteger {
234 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformBufferOffset)) }
235 }
236
237 #[inline]
241 pub fn set_motion_transform_buffer_offset(&self, offset: UInteger) {
242 unsafe {
243 msg_send_1::<(), UInteger>(
244 self.as_ptr(),
245 sel!(setMotionTransformBufferOffset:),
246 offset,
247 );
248 }
249 }
250
251 #[inline]
255 pub fn motion_transform_count(&self) -> UInteger {
256 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformCount)) }
257 }
258
259 #[inline]
263 pub fn set_motion_transform_count(&self, count: UInteger) {
264 unsafe {
265 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setMotionTransformCount:), count);
266 }
267 }
268
269 #[inline]
273 pub fn motion_transform_stride(&self) -> UInteger {
274 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformStride)) }
275 }
276
277 #[inline]
281 pub fn set_motion_transform_stride(&self, stride: UInteger) {
282 unsafe {
283 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setMotionTransformStride:), stride);
284 }
285 }
286
287 #[inline]
291 pub fn motion_transform_type(&self) -> TransformType {
292 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformType)) }
293 }
294
295 #[inline]
299 pub fn set_motion_transform_type(&self, transform_type: TransformType) {
300 unsafe {
301 msg_send_1::<(), TransformType>(
302 self.as_ptr(),
303 sel!(setMotionTransformType:),
304 transform_type,
305 );
306 }
307 }
308
309 #[inline]
318 pub fn instanced_acceleration_structures_ptr(&self) -> *const c_void {
319 unsafe { msg_send_0(self.as_ptr(), sel!(instancedAccelerationStructures)) }
320 }
321
322 pub unsafe fn set_instanced_acceleration_structures_ptr(
330 &self,
331 instanced_acceleration_structures: *const c_void,
332 ) {
333 unsafe {
334 msg_send_1::<(), *const c_void>(
335 self.as_ptr(),
336 sel!(setInstancedAccelerationStructures:),
337 instanced_acceleration_structures,
338 );
339 }
340 }
341}
342
343impl Default for InstanceAccelerationStructureDescriptor {
344 fn default() -> Self {
345 Self::new().expect("failed to create instance acceleration structure descriptor")
346 }
347}
348
349impl Clone for InstanceAccelerationStructureDescriptor {
350 fn clone(&self) -> Self {
351 unsafe {
352 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
353 Self::from_raw(ptr).expect("failed to copy descriptor")
354 }
355 }
356}
357
358impl Drop for InstanceAccelerationStructureDescriptor {
359 fn drop(&mut self) {
360 unsafe {
361 msg_send_0::<()>(self.as_ptr(), sel!(release));
362 }
363 }
364}
365
366impl Referencing for InstanceAccelerationStructureDescriptor {
367 #[inline]
368 fn as_ptr(&self) -> *const c_void {
369 self.0.as_ptr()
370 }
371}
372
373unsafe impl Send for InstanceAccelerationStructureDescriptor {}
374unsafe impl Sync for InstanceAccelerationStructureDescriptor {}
375
376#[repr(transparent)]
384pub struct IndirectInstanceAccelerationStructureDescriptor(pub(crate) NonNull<c_void>);
385
386impl IndirectInstanceAccelerationStructureDescriptor {
387 pub fn new() -> Option<Self> {
391 unsafe {
392 let class =
393 mtl_sys::Class::get("MTLIndirectInstanceAccelerationStructureDescriptor")?;
394 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
395 if ptr.is_null() {
396 return None;
397 }
398 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
399 Self::from_raw(ptr)
400 }
401 }
402
403 #[inline]
409 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
410 NonNull::new(ptr).map(Self)
411 }
412
413 #[inline]
415 pub fn as_raw(&self) -> *mut c_void {
416 self.0.as_ptr()
417 }
418
419 #[inline]
423 pub fn usage(&self) -> AccelerationStructureUsage {
424 unsafe { msg_send_0(self.as_ptr(), sel!(usage)) }
425 }
426
427 #[inline]
431 pub fn set_usage(&self, usage: AccelerationStructureUsage) {
432 unsafe {
433 msg_send_1::<(), AccelerationStructureUsage>(self.as_ptr(), sel!(setUsage:), usage);
434 }
435 }
436
437 #[inline]
441 pub fn max_instance_count(&self) -> UInteger {
442 unsafe { msg_send_0(self.as_ptr(), sel!(maxInstanceCount)) }
443 }
444
445 #[inline]
449 pub fn set_max_instance_count(&self, count: UInteger) {
450 unsafe {
451 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setMaxInstanceCount:), count);
452 }
453 }
454
455 pub fn instance_count_buffer(&self) -> Option<Buffer> {
459 unsafe {
460 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(instanceCountBuffer));
461 if ptr.is_null() {
462 return None;
463 }
464 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
465 Buffer::from_raw(ptr)
466 }
467 }
468
469 pub fn set_instance_count_buffer(&self, buffer: Option<&Buffer>) {
473 unsafe {
474 msg_send_1::<(), *const c_void>(
475 self.as_ptr(),
476 sel!(setInstanceCountBuffer:),
477 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
478 );
479 }
480 }
481
482 #[inline]
486 pub fn instance_count_buffer_offset(&self) -> UInteger {
487 unsafe { msg_send_0(self.as_ptr(), sel!(instanceCountBufferOffset)) }
488 }
489
490 #[inline]
494 pub fn set_instance_count_buffer_offset(&self, offset: UInteger) {
495 unsafe {
496 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setInstanceCountBufferOffset:), offset);
497 }
498 }
499
500 pub fn instance_descriptor_buffer(&self) -> Option<Buffer> {
504 unsafe {
505 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(instanceDescriptorBuffer));
506 if ptr.is_null() {
507 return None;
508 }
509 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
510 Buffer::from_raw(ptr)
511 }
512 }
513
514 pub fn set_instance_descriptor_buffer(&self, buffer: Option<&Buffer>) {
518 unsafe {
519 msg_send_1::<(), *const c_void>(
520 self.as_ptr(),
521 sel!(setInstanceDescriptorBuffer:),
522 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
523 );
524 }
525 }
526
527 #[inline]
531 pub fn instance_descriptor_buffer_offset(&self) -> UInteger {
532 unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorBufferOffset)) }
533 }
534
535 #[inline]
539 pub fn set_instance_descriptor_buffer_offset(&self, offset: UInteger) {
540 unsafe {
541 msg_send_1::<(), UInteger>(
542 self.as_ptr(),
543 sel!(setInstanceDescriptorBufferOffset:),
544 offset,
545 );
546 }
547 }
548
549 #[inline]
553 pub fn instance_descriptor_stride(&self) -> UInteger {
554 unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorStride)) }
555 }
556
557 #[inline]
561 pub fn set_instance_descriptor_stride(&self, stride: UInteger) {
562 unsafe {
563 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setInstanceDescriptorStride:), stride);
564 }
565 }
566
567 #[inline]
571 pub fn instance_descriptor_type(&self) -> AccelerationStructureInstanceDescriptorType {
572 unsafe { msg_send_0(self.as_ptr(), sel!(instanceDescriptorType)) }
573 }
574
575 #[inline]
579 pub fn set_instance_descriptor_type(
580 &self,
581 descriptor_type: AccelerationStructureInstanceDescriptorType,
582 ) {
583 unsafe {
584 msg_send_1::<(), AccelerationStructureInstanceDescriptorType>(
585 self.as_ptr(),
586 sel!(setInstanceDescriptorType:),
587 descriptor_type,
588 );
589 }
590 }
591
592 #[inline]
596 pub fn instance_transformation_matrix_layout(&self) -> MatrixLayout {
597 unsafe { msg_send_0(self.as_ptr(), sel!(instanceTransformationMatrixLayout)) }
598 }
599
600 #[inline]
604 pub fn set_instance_transformation_matrix_layout(&self, layout: MatrixLayout) {
605 unsafe {
606 msg_send_1::<(), MatrixLayout>(
607 self.as_ptr(),
608 sel!(setInstanceTransformationMatrixLayout:),
609 layout,
610 );
611 }
612 }
613
614 #[inline]
618 pub fn max_motion_transform_count(&self) -> UInteger {
619 unsafe { msg_send_0(self.as_ptr(), sel!(maxMotionTransformCount)) }
620 }
621
622 #[inline]
626 pub fn set_max_motion_transform_count(&self, count: UInteger) {
627 unsafe {
628 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setMaxMotionTransformCount:), count);
629 }
630 }
631
632 pub fn motion_transform_buffer(&self) -> Option<Buffer> {
636 unsafe {
637 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(motionTransformBuffer));
638 if ptr.is_null() {
639 return None;
640 }
641 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
642 Buffer::from_raw(ptr)
643 }
644 }
645
646 pub fn set_motion_transform_buffer(&self, buffer: Option<&Buffer>) {
650 unsafe {
651 msg_send_1::<(), *const c_void>(
652 self.as_ptr(),
653 sel!(setMotionTransformBuffer:),
654 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
655 );
656 }
657 }
658
659 #[inline]
663 pub fn motion_transform_buffer_offset(&self) -> UInteger {
664 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformBufferOffset)) }
665 }
666
667 #[inline]
671 pub fn set_motion_transform_buffer_offset(&self, offset: UInteger) {
672 unsafe {
673 msg_send_1::<(), UInteger>(
674 self.as_ptr(),
675 sel!(setMotionTransformBufferOffset:),
676 offset,
677 );
678 }
679 }
680
681 pub fn motion_transform_count_buffer(&self) -> Option<Buffer> {
685 unsafe {
686 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(motionTransformCountBuffer));
687 if ptr.is_null() {
688 return None;
689 }
690 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
691 Buffer::from_raw(ptr)
692 }
693 }
694
695 pub fn set_motion_transform_count_buffer(&self, buffer: Option<&Buffer>) {
699 unsafe {
700 msg_send_1::<(), *const c_void>(
701 self.as_ptr(),
702 sel!(setMotionTransformCountBuffer:),
703 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
704 );
705 }
706 }
707
708 #[inline]
712 pub fn motion_transform_count_buffer_offset(&self) -> UInteger {
713 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformCountBufferOffset)) }
714 }
715
716 #[inline]
720 pub fn set_motion_transform_count_buffer_offset(&self, offset: UInteger) {
721 unsafe {
722 msg_send_1::<(), UInteger>(
723 self.as_ptr(),
724 sel!(setMotionTransformCountBufferOffset:),
725 offset,
726 );
727 }
728 }
729
730 #[inline]
734 pub fn motion_transform_stride(&self) -> UInteger {
735 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformStride)) }
736 }
737
738 #[inline]
742 pub fn set_motion_transform_stride(&self, stride: UInteger) {
743 unsafe {
744 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setMotionTransformStride:), stride);
745 }
746 }
747
748 #[inline]
752 pub fn motion_transform_type(&self) -> TransformType {
753 unsafe { msg_send_0(self.as_ptr(), sel!(motionTransformType)) }
754 }
755
756 #[inline]
760 pub fn set_motion_transform_type(&self, transform_type: TransformType) {
761 unsafe {
762 msg_send_1::<(), TransformType>(
763 self.as_ptr(),
764 sel!(setMotionTransformType:),
765 transform_type,
766 );
767 }
768 }
769}
770
771impl Default for IndirectInstanceAccelerationStructureDescriptor {
772 fn default() -> Self {
773 Self::new().expect("failed to create indirect instance acceleration structure descriptor")
774 }
775}
776
777impl Clone for IndirectInstanceAccelerationStructureDescriptor {
778 fn clone(&self) -> Self {
779 unsafe {
780 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
781 Self::from_raw(ptr).expect("failed to copy descriptor")
782 }
783 }
784}
785
786impl Drop for IndirectInstanceAccelerationStructureDescriptor {
787 fn drop(&mut self) {
788 unsafe {
789 msg_send_0::<()>(self.as_ptr(), sel!(release));
790 }
791 }
792}
793
794impl Referencing for IndirectInstanceAccelerationStructureDescriptor {
795 #[inline]
796 fn as_ptr(&self) -> *const c_void {
797 self.0.as_ptr()
798 }
799}
800
801unsafe impl Send for IndirectInstanceAccelerationStructureDescriptor {}
802unsafe impl Sync for IndirectInstanceAccelerationStructureDescriptor {}