mtl_gpu/acceleration/geometry/
base.rs1use 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::Buffer;
10
11#[repr(transparent)]
15pub struct AccelerationStructureGeometryDescriptor(pub(crate) NonNull<c_void>);
16
17impl AccelerationStructureGeometryDescriptor {
18 pub fn new() -> Option<Self> {
22 unsafe {
23 let class = mtl_sys::Class::get("MTLAccelerationStructureGeometryDescriptor")?;
24 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
25 if ptr.is_null() {
26 return None;
27 }
28 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
29 Self::from_raw(ptr)
30 }
31 }
32
33 #[inline]
39 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
40 NonNull::new(ptr).map(Self)
41 }
42
43 #[inline]
45 pub fn as_raw(&self) -> *mut c_void {
46 self.0.as_ptr()
47 }
48
49 #[inline]
53 pub fn allow_duplicate_intersection_function_invocation(&self) -> bool {
54 unsafe {
55 msg_send_0(
56 self.as_ptr(),
57 sel!(allowDuplicateIntersectionFunctionInvocation),
58 )
59 }
60 }
61
62 #[inline]
66 pub fn set_allow_duplicate_intersection_function_invocation(&self, allow: bool) {
67 unsafe {
68 msg_send_1::<(), bool>(
69 self.as_ptr(),
70 sel!(setAllowDuplicateIntersectionFunctionInvocation:),
71 allow,
72 );
73 }
74 }
75
76 #[inline]
80 pub fn intersection_function_table_offset(&self) -> UInteger {
81 unsafe { msg_send_0(self.as_ptr(), sel!(intersectionFunctionTableOffset)) }
82 }
83
84 #[inline]
88 pub fn set_intersection_function_table_offset(&self, offset: UInteger) {
89 unsafe {
90 msg_send_1::<(), UInteger>(
91 self.as_ptr(),
92 sel!(setIntersectionFunctionTableOffset:),
93 offset,
94 );
95 }
96 }
97
98 #[inline]
102 pub fn opaque(&self) -> bool {
103 unsafe { msg_send_0(self.as_ptr(), sel!(opaque)) }
104 }
105
106 #[inline]
110 pub fn set_opaque(&self, opaque: bool) {
111 unsafe {
112 msg_send_1::<(), bool>(self.as_ptr(), sel!(setOpaque:), opaque);
113 }
114 }
115
116 pub fn label(&self) -> Option<String> {
120 unsafe {
121 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
122 if ptr.is_null() {
123 return None;
124 }
125 let utf8_ptr: *const std::ffi::c_char =
126 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
127 if utf8_ptr.is_null() {
128 return None;
129 }
130 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
131 Some(c_str.to_string_lossy().into_owned())
132 }
133 }
134
135 pub fn set_label(&self, label: &str) {
139 if let Some(ns_label) = mtl_foundation::String::from_str(label) {
140 unsafe {
141 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
142 }
143 }
144 }
145
146 pub fn primitive_data_buffer(&self) -> Option<Buffer> {
150 unsafe {
151 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(primitiveDataBuffer));
152 if ptr.is_null() {
153 return None;
154 }
155 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
156 Buffer::from_raw(ptr)
157 }
158 }
159
160 pub fn set_primitive_data_buffer(&self, buffer: Option<&Buffer>) {
164 unsafe {
165 msg_send_1::<(), *const c_void>(
166 self.as_ptr(),
167 sel!(setPrimitiveDataBuffer:),
168 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
169 );
170 }
171 }
172
173 #[inline]
177 pub fn primitive_data_buffer_offset(&self) -> UInteger {
178 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataBufferOffset)) }
179 }
180
181 #[inline]
185 pub fn set_primitive_data_buffer_offset(&self, offset: UInteger) {
186 unsafe {
187 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataBufferOffset:), offset);
188 }
189 }
190
191 #[inline]
195 pub fn primitive_data_element_size(&self) -> UInteger {
196 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataElementSize)) }
197 }
198
199 #[inline]
203 pub fn set_primitive_data_element_size(&self, size: UInteger) {
204 unsafe {
205 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataElementSize:), size);
206 }
207 }
208
209 #[inline]
213 pub fn primitive_data_stride(&self) -> UInteger {
214 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataStride)) }
215 }
216
217 #[inline]
221 pub fn set_primitive_data_stride(&self, stride: UInteger) {
222 unsafe {
223 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataStride:), stride);
224 }
225 }
226}
227
228impl Default for AccelerationStructureGeometryDescriptor {
229 fn default() -> Self {
230 Self::new().expect("failed to create geometry descriptor")
231 }
232}
233
234impl Clone for AccelerationStructureGeometryDescriptor {
235 fn clone(&self) -> Self {
236 unsafe {
237 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
238 Self::from_raw(ptr).expect("failed to copy geometry descriptor")
239 }
240 }
241}
242
243impl Drop for AccelerationStructureGeometryDescriptor {
244 fn drop(&mut self) {
245 unsafe {
246 msg_send_0::<()>(self.as_ptr(), sel!(release));
247 }
248 }
249}
250
251impl Referencing for AccelerationStructureGeometryDescriptor {
252 #[inline]
253 fn as_ptr(&self) -> *const c_void {
254 self.0.as_ptr()
255 }
256}
257
258unsafe impl Send for AccelerationStructureGeometryDescriptor {}
259unsafe impl Sync for AccelerationStructureGeometryDescriptor {}