mtl_gpu/acceleration/geometry/
triangle.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;
10use crate::enums::{AttributeFormat, IndexType, MatrixLayout};
11
12#[repr(transparent)]
16pub struct AccelerationStructureTriangleGeometryDescriptor(pub(crate) NonNull<c_void>);
17
18impl AccelerationStructureTriangleGeometryDescriptor {
19 pub fn new() -> Option<Self> {
23 unsafe {
24 let class =
25 mtl_sys::Class::get("MTLAccelerationStructureTriangleGeometryDescriptor")?;
26 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
27 if ptr.is_null() {
28 return None;
29 }
30 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
31 Self::from_raw(ptr)
32 }
33 }
34
35 #[inline]
41 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
42 NonNull::new(ptr).map(Self)
43 }
44
45 #[inline]
47 pub fn as_raw(&self) -> *mut c_void {
48 self.0.as_ptr()
49 }
50
51 #[inline]
55 pub fn allow_duplicate_intersection_function_invocation(&self) -> bool {
56 unsafe {
57 msg_send_0(
58 self.as_ptr(),
59 sel!(allowDuplicateIntersectionFunctionInvocation),
60 )
61 }
62 }
63
64 #[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]
78 pub fn intersection_function_table_offset(&self) -> UInteger {
79 unsafe { msg_send_0(self.as_ptr(), sel!(intersectionFunctionTableOffset)) }
80 }
81
82 #[inline]
84 pub fn set_intersection_function_table_offset(&self, offset: UInteger) {
85 unsafe {
86 msg_send_1::<(), UInteger>(
87 self.as_ptr(),
88 sel!(setIntersectionFunctionTableOffset:),
89 offset,
90 );
91 }
92 }
93
94 #[inline]
96 pub fn opaque(&self) -> bool {
97 unsafe { msg_send_0(self.as_ptr(), sel!(opaque)) }
98 }
99
100 #[inline]
102 pub fn set_opaque(&self, opaque: bool) {
103 unsafe {
104 msg_send_1::<(), bool>(self.as_ptr(), sel!(setOpaque:), opaque);
105 }
106 }
107
108 pub fn label(&self) -> Option<String> {
110 unsafe {
111 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
112 if ptr.is_null() {
113 return None;
114 }
115 let utf8_ptr: *const std::ffi::c_char =
116 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
117 if utf8_ptr.is_null() {
118 return None;
119 }
120 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
121 Some(c_str.to_string_lossy().into_owned())
122 }
123 }
124
125 pub fn set_label(&self, label: &str) {
127 if let Some(ns_label) = mtl_foundation::String::from_str(label) {
128 unsafe {
129 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
130 }
131 }
132 }
133
134 pub fn primitive_data_buffer(&self) -> Option<Buffer> {
136 unsafe {
137 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(primitiveDataBuffer));
138 if ptr.is_null() {
139 return None;
140 }
141 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
142 Buffer::from_raw(ptr)
143 }
144 }
145
146 pub fn set_primitive_data_buffer(&self, buffer: Option<&Buffer>) {
148 unsafe {
149 msg_send_1::<(), *const c_void>(
150 self.as_ptr(),
151 sel!(setPrimitiveDataBuffer:),
152 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
153 );
154 }
155 }
156
157 #[inline]
159 pub fn primitive_data_buffer_offset(&self) -> UInteger {
160 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataBufferOffset)) }
161 }
162
163 #[inline]
165 pub fn set_primitive_data_buffer_offset(&self, offset: UInteger) {
166 unsafe {
167 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataBufferOffset:), offset);
168 }
169 }
170
171 #[inline]
173 pub fn primitive_data_element_size(&self) -> UInteger {
174 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataElementSize)) }
175 }
176
177 #[inline]
179 pub fn set_primitive_data_element_size(&self, size: UInteger) {
180 unsafe {
181 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataElementSize:), size);
182 }
183 }
184
185 #[inline]
187 pub fn primitive_data_stride(&self) -> UInteger {
188 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataStride)) }
189 }
190
191 #[inline]
193 pub fn set_primitive_data_stride(&self, stride: UInteger) {
194 unsafe {
195 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataStride:), stride);
196 }
197 }
198
199 pub fn index_buffer(&self) -> Option<Buffer> {
205 unsafe {
206 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(indexBuffer));
207 if ptr.is_null() {
208 return None;
209 }
210 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
211 Buffer::from_raw(ptr)
212 }
213 }
214
215 pub fn set_index_buffer(&self, buffer: Option<&Buffer>) {
219 unsafe {
220 msg_send_1::<(), *const c_void>(
221 self.as_ptr(),
222 sel!(setIndexBuffer:),
223 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
224 );
225 }
226 }
227
228 #[inline]
232 pub fn index_buffer_offset(&self) -> UInteger {
233 unsafe { msg_send_0(self.as_ptr(), sel!(indexBufferOffset)) }
234 }
235
236 #[inline]
240 pub fn set_index_buffer_offset(&self, offset: UInteger) {
241 unsafe {
242 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setIndexBufferOffset:), offset);
243 }
244 }
245
246 #[inline]
250 pub fn index_type(&self) -> IndexType {
251 unsafe { msg_send_0(self.as_ptr(), sel!(indexType)) }
252 }
253
254 #[inline]
258 pub fn set_index_type(&self, index_type: IndexType) {
259 unsafe {
260 msg_send_1::<(), IndexType>(self.as_ptr(), sel!(setIndexType:), index_type);
261 }
262 }
263
264 pub fn vertex_buffer(&self) -> Option<Buffer> {
268 unsafe {
269 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(vertexBuffer));
270 if ptr.is_null() {
271 return None;
272 }
273 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
274 Buffer::from_raw(ptr)
275 }
276 }
277
278 pub fn set_vertex_buffer(&self, buffer: Option<&Buffer>) {
282 unsafe {
283 msg_send_1::<(), *const c_void>(
284 self.as_ptr(),
285 sel!(setVertexBuffer:),
286 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
287 );
288 }
289 }
290
291 #[inline]
295 pub fn vertex_buffer_offset(&self) -> UInteger {
296 unsafe { msg_send_0(self.as_ptr(), sel!(vertexBufferOffset)) }
297 }
298
299 #[inline]
303 pub fn set_vertex_buffer_offset(&self, offset: UInteger) {
304 unsafe {
305 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setVertexBufferOffset:), offset);
306 }
307 }
308
309 #[inline]
313 pub fn vertex_format(&self) -> AttributeFormat {
314 unsafe { msg_send_0(self.as_ptr(), sel!(vertexFormat)) }
315 }
316
317 #[inline]
321 pub fn set_vertex_format(&self, format: AttributeFormat) {
322 unsafe {
323 msg_send_1::<(), AttributeFormat>(self.as_ptr(), sel!(setVertexFormat:), format);
324 }
325 }
326
327 #[inline]
331 pub fn vertex_stride(&self) -> UInteger {
332 unsafe { msg_send_0(self.as_ptr(), sel!(vertexStride)) }
333 }
334
335 #[inline]
339 pub fn set_vertex_stride(&self, stride: UInteger) {
340 unsafe {
341 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setVertexStride:), stride);
342 }
343 }
344
345 #[inline]
349 pub fn triangle_count(&self) -> UInteger {
350 unsafe { msg_send_0(self.as_ptr(), sel!(triangleCount)) }
351 }
352
353 #[inline]
357 pub fn set_triangle_count(&self, count: UInteger) {
358 unsafe {
359 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setTriangleCount:), count);
360 }
361 }
362
363 pub fn transformation_matrix_buffer(&self) -> Option<Buffer> {
367 unsafe {
368 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(transformationMatrixBuffer));
369 if ptr.is_null() {
370 return None;
371 }
372 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
373 Buffer::from_raw(ptr)
374 }
375 }
376
377 pub fn set_transformation_matrix_buffer(&self, buffer: Option<&Buffer>) {
381 unsafe {
382 msg_send_1::<(), *const c_void>(
383 self.as_ptr(),
384 sel!(setTransformationMatrixBuffer:),
385 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
386 );
387 }
388 }
389
390 #[inline]
394 pub fn transformation_matrix_buffer_offset(&self) -> UInteger {
395 unsafe { msg_send_0(self.as_ptr(), sel!(transformationMatrixBufferOffset)) }
396 }
397
398 #[inline]
402 pub fn set_transformation_matrix_buffer_offset(&self, offset: UInteger) {
403 unsafe {
404 msg_send_1::<(), UInteger>(
405 self.as_ptr(),
406 sel!(setTransformationMatrixBufferOffset:),
407 offset,
408 );
409 }
410 }
411
412 #[inline]
416 pub fn transformation_matrix_layout(&self) -> MatrixLayout {
417 unsafe { msg_send_0(self.as_ptr(), sel!(transformationMatrixLayout)) }
418 }
419
420 #[inline]
424 pub fn set_transformation_matrix_layout(&self, layout: MatrixLayout) {
425 unsafe {
426 msg_send_1::<(), MatrixLayout>(
427 self.as_ptr(),
428 sel!(setTransformationMatrixLayout:),
429 layout,
430 );
431 }
432 }
433}
434
435impl Default for AccelerationStructureTriangleGeometryDescriptor {
436 fn default() -> Self {
437 Self::new().expect("failed to create triangle geometry descriptor")
438 }
439}
440
441impl Clone for AccelerationStructureTriangleGeometryDescriptor {
442 fn clone(&self) -> Self {
443 unsafe {
444 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
445 Self::from_raw(ptr).expect("failed to copy triangle geometry descriptor")
446 }
447 }
448}
449
450impl Drop for AccelerationStructureTriangleGeometryDescriptor {
451 fn drop(&mut self) {
452 unsafe {
453 msg_send_0::<()>(self.as_ptr(), sel!(release));
454 }
455 }
456}
457
458impl Referencing for AccelerationStructureTriangleGeometryDescriptor {
459 #[inline]
460 fn as_ptr(&self) -> *const c_void {
461 self.0.as_ptr()
462 }
463}
464
465unsafe impl Send for AccelerationStructureTriangleGeometryDescriptor {}
466unsafe impl Sync for AccelerationStructureTriangleGeometryDescriptor {}