Skip to main content

mtl_gpu/acceleration/
structure.rs

1//! Core acceleration structure types.
2//!
3//! Contains `AccelerationStructure` and `AccelerationStructureSizes`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::{msg_send_0, msg_send_1, sel};
10
11pub struct AccelerationStructure(pub(crate) NonNull<c_void>);
12
13impl AccelerationStructure {
14    /// Create an AccelerationStructure from a raw pointer.
15    ///
16    /// # Safety
17    ///
18    /// The pointer must be a valid Metal acceleration structure object.
19    #[inline]
20    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
21        NonNull::new(ptr).map(Self)
22    }
23
24    /// Get the raw pointer.
25    #[inline]
26    pub fn as_raw(&self) -> *mut c_void {
27        self.0.as_ptr()
28    }
29
30    /// Get the size in bytes of the acceleration structure.
31    ///
32    /// C++ equivalent: `NS::UInteger size() const`
33    #[inline]
34    pub fn size(&self) -> UInteger {
35        unsafe { msg_send_0(self.as_ptr(), sel!(size)) }
36    }
37
38    /// Get the GPU resource ID.
39    ///
40    /// C++ equivalent: `ResourceID gpuResourceID() const`
41    #[inline]
42    pub fn gpu_resource_id(&self) -> u64 {
43        unsafe { msg_send_0(self.as_ptr(), sel!(gpuResourceID)) }
44    }
45
46    /// Get the label.
47    ///
48    /// C++ equivalent: `NS::String* label() const`
49    pub fn label(&self) -> Option<String> {
50        unsafe {
51            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
52            if ptr.is_null() {
53                return None;
54            }
55            let utf8_ptr: *const std::ffi::c_char =
56                mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
57            if utf8_ptr.is_null() {
58                return None;
59            }
60            let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
61            Some(c_str.to_string_lossy().into_owned())
62        }
63    }
64
65    /// Set the label.
66    ///
67    /// C++ equivalent: `void setLabel(const NS::String*)`
68    pub fn set_label(&self, label: &str) {
69        if let Some(ns_label) = mtl_foundation::String::from_str(label) {
70            unsafe {
71                msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
72            }
73        }
74    }
75}
76
77impl Clone for AccelerationStructure {
78    fn clone(&self) -> Self {
79        unsafe {
80            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
81        }
82        Self(self.0)
83    }
84}
85
86impl Drop for AccelerationStructure {
87    fn drop(&mut self) {
88        unsafe {
89            msg_send_0::<()>(self.as_ptr(), sel!(release));
90        }
91    }
92}
93
94impl Referencing for AccelerationStructure {
95    #[inline]
96    fn as_ptr(&self) -> *const c_void {
97        self.0.as_ptr()
98    }
99}
100
101unsafe impl Send for AccelerationStructure {}
102unsafe impl Sync for AccelerationStructure {}
103
104impl std::fmt::Debug for AccelerationStructure {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        f.debug_struct("AccelerationStructure")
107            .field("size", &self.size())
108            .field("label", &self.label())
109            .finish()
110    }
111}
112
113// ============================================================================
114// AccelerationStructureSizes
115// ============================================================================
116
117/// Sizes required for building an acceleration structure.
118///
119/// C++ equivalent: `MTL::AccelerationStructureSizes`
120#[repr(C)]
121#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
122pub struct AccelerationStructureSizes {
123    /// The size of the acceleration structure in bytes.
124    pub acceleration_structure_size: UInteger,
125    /// The size of the scratch buffer needed during building.
126    pub build_scratch_buffer_size: UInteger,
127    /// The size of the scratch buffer needed during refitting.
128    pub refit_scratch_buffer_size: UInteger,
129}