mtl_gpu/encoder/render_encoder/advanced.rs
1//! Advanced render encoder features.
2//!
3//! This module contains methods for:
4//! - Memory barriers
5//! - Resource usage declarations
6//! - Fence operations
7//! - Vertex amplification
8//! - Acceleration structure bindings
9//! - Function table bindings
10//! - Indirect command execution
11//! - Counter sampling
12
13use std::ffi::c_void;
14
15use mtl_foundation::{Referencing, UInteger};
16use mtl_sys::{msg_send_0, msg_send_1, sel};
17
18use crate::Buffer;
19use crate::Texture;
20use crate::enums::{BarrierScope, RenderStages, ResourceUsage};
21use crate::types::VertexAmplificationViewMapping;
22
23use super::RenderCommandEncoder;
24
25impl RenderCommandEncoder {
26 // =========================================================================
27 // Memory Barriers
28 // =========================================================================
29
30 /// Insert a memory barrier with scope.
31 ///
32 /// C++ equivalent: `void memoryBarrier(MTL::BarrierScope, MTL::RenderStages, MTL::RenderStages)`
33 #[inline]
34 pub fn memory_barrier_with_scope(
35 &self,
36 scope: BarrierScope,
37 after_stages: RenderStages,
38 before_stages: RenderStages,
39 ) {
40 unsafe {
41 mtl_sys::msg_send_3::<(), BarrierScope, RenderStages, RenderStages>(
42 self.as_ptr(),
43 sel!(memoryBarrierWithScope: afterStages: beforeStages:),
44 scope,
45 after_stages,
46 before_stages,
47 );
48 }
49 }
50
51 /// Insert a texture barrier (deprecated).
52 ///
53 /// C++ equivalent: `void textureBarrier()`
54 #[inline]
55 pub fn texture_barrier(&self) {
56 unsafe {
57 msg_send_0::<()>(self.as_ptr(), sel!(textureBarrier));
58 }
59 }
60
61 /// Insert a memory barrier for specific resources (raw pointer version).
62 ///
63 /// C++ equivalent: `void memoryBarrier(const Resource* const*, NS::UInteger, MTL::RenderStages, MTL::RenderStages)`
64 ///
65 /// # Safety
66 ///
67 /// The resources pointer must be a valid array with the specified count.
68 #[inline]
69 pub unsafe fn memory_barrier_with_resources_ptr(
70 &self,
71 resources: *const *const c_void,
72 count: UInteger,
73 after_stages: RenderStages,
74 before_stages: RenderStages,
75 ) {
76 unsafe {
77 mtl_sys::msg_send_4::<(), *const *const c_void, UInteger, RenderStages, RenderStages>(
78 self.as_ptr(),
79 sel!(memoryBarrierWithResources: count: afterStages: beforeStages:),
80 resources,
81 count,
82 after_stages,
83 before_stages,
84 );
85 }
86 }
87
88 // =========================================================================
89 // Resource Usage
90 // =========================================================================
91
92 /// Declare that a resource will be used (raw pointer version).
93 ///
94 /// C++ equivalent: `void useResource(const Resource*, MTL::ResourceUsage)`
95 ///
96 /// # Safety
97 ///
98 /// The resource pointer must be a valid Metal resource object.
99 #[inline]
100 pub unsafe fn use_resource_ptr(&self, resource: *const c_void, usage: ResourceUsage) {
101 unsafe {
102 mtl_sys::msg_send_2::<(), *const c_void, ResourceUsage>(
103 self.as_ptr(),
104 sel!(useResource: usage:),
105 resource,
106 usage,
107 );
108 }
109 }
110
111 /// Declare that a resource will be used with stages (raw pointer version).
112 ///
113 /// C++ equivalent: `void useResource(const Resource*, MTL::ResourceUsage, MTL::RenderStages)`
114 ///
115 /// # Safety
116 ///
117 /// The resource pointer must be a valid Metal resource object.
118 #[inline]
119 pub unsafe fn use_resource_ptr_with_stages(
120 &self,
121 resource: *const c_void,
122 usage: ResourceUsage,
123 stages: RenderStages,
124 ) {
125 unsafe {
126 mtl_sys::msg_send_3::<(), *const c_void, ResourceUsage, RenderStages>(
127 self.as_ptr(),
128 sel!(useResource: usage: stages:),
129 resource,
130 usage,
131 stages,
132 );
133 }
134 }
135
136 /// Declare that a buffer will be used.
137 ///
138 /// C++ equivalent: `void useResource(const Resource*, MTL::ResourceUsage)`
139 #[inline]
140 pub fn use_buffer(&self, buffer: &Buffer, usage: ResourceUsage) {
141 unsafe { self.use_resource_ptr(buffer.as_ptr(), usage) };
142 }
143
144 /// Declare that a texture will be used.
145 ///
146 /// C++ equivalent: `void useResource(const Resource*, MTL::ResourceUsage)`
147 #[inline]
148 pub fn use_texture(&self, texture: &Texture, usage: ResourceUsage) {
149 unsafe { self.use_resource_ptr(texture.as_ptr(), usage) };
150 }
151
152 /// Declare that a heap will be used (raw pointer version).
153 ///
154 /// C++ equivalent: `void useHeap(const Heap*)`
155 ///
156 /// # Safety
157 ///
158 /// The heap pointer must be a valid Metal heap object.
159 #[inline]
160 pub unsafe fn use_heap_ptr(&self, heap: *const c_void) {
161 unsafe {
162 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(useHeap:), heap);
163 }
164 }
165
166 /// Declare that a heap will be used.
167 ///
168 /// C++ equivalent: `void useHeap(const Heap*)`
169 #[inline]
170 pub fn use_heap(&self, heap: &crate::Heap) {
171 unsafe { self.use_heap_ptr(heap.as_ptr()) };
172 }
173
174 /// Declare that a heap will be used with stages (raw pointer version).
175 ///
176 /// C++ equivalent: `void useHeap(const Heap*, MTL::RenderStages)`
177 ///
178 /// # Safety
179 ///
180 /// The heap pointer must be a valid Metal heap object.
181 #[inline]
182 pub unsafe fn use_heap_ptr_with_stages(&self, heap: *const c_void, stages: RenderStages) {
183 unsafe {
184 mtl_sys::msg_send_2::<(), *const c_void, RenderStages>(
185 self.as_ptr(),
186 sel!(useHeap: stages:),
187 heap,
188 stages,
189 );
190 }
191 }
192
193 /// Declare that multiple heaps will be used (raw pointer version).
194 ///
195 /// C++ equivalent: `void useHeaps(const Heap* const*, NS::UInteger)`
196 ///
197 /// # Safety
198 ///
199 /// The heaps pointer must be a valid array of heap pointers with the specified count.
200 #[inline]
201 pub unsafe fn use_heaps_ptr(&self, heaps: *const *const c_void, count: UInteger) {
202 unsafe {
203 mtl_sys::msg_send_2::<(), *const *const c_void, UInteger>(
204 self.as_ptr(),
205 sel!(useHeaps: count:),
206 heaps,
207 count,
208 );
209 }
210 }
211
212 /// Declare that multiple heaps will be used with stages (raw pointer version).
213 ///
214 /// C++ equivalent: `void useHeaps(const Heap* const*, NS::UInteger, MTL::RenderStages)`
215 ///
216 /// # Safety
217 ///
218 /// The heaps pointer must be a valid array of heap pointers with the specified count.
219 #[inline]
220 pub unsafe fn use_heaps_with_stages_ptr(
221 &self,
222 heaps: *const *const c_void,
223 count: UInteger,
224 stages: RenderStages,
225 ) {
226 unsafe {
227 mtl_sys::msg_send_3::<(), *const *const c_void, UInteger, RenderStages>(
228 self.as_ptr(),
229 sel!(useHeaps: count: stages:),
230 heaps,
231 count,
232 stages,
233 );
234 }
235 }
236
237 /// Declare that multiple resources will be used (raw pointer version).
238 ///
239 /// C++ equivalent: `void useResources(const Resource* const*, NS::UInteger, MTL::ResourceUsage)`
240 ///
241 /// # Safety
242 ///
243 /// The resources pointer must be a valid array of resource pointers with the specified count.
244 #[inline]
245 pub unsafe fn use_resources_ptr(
246 &self,
247 resources: *const *const c_void,
248 count: UInteger,
249 usage: ResourceUsage,
250 ) {
251 unsafe {
252 mtl_sys::msg_send_3::<(), *const *const c_void, UInteger, ResourceUsage>(
253 self.as_ptr(),
254 sel!(useResources: count: usage:),
255 resources,
256 count,
257 usage,
258 );
259 }
260 }
261
262 /// Declare that multiple resources will be used with stages (raw pointer version).
263 ///
264 /// C++ equivalent: `void useResources(const Resource* const*, NS::UInteger, MTL::ResourceUsage, MTL::RenderStages)`
265 ///
266 /// # Safety
267 ///
268 /// The resources pointer must be a valid array of resource pointers with the specified count.
269 #[inline]
270 pub unsafe fn use_resources_with_stages_ptr(
271 &self,
272 resources: *const *const c_void,
273 count: UInteger,
274 usage: ResourceUsage,
275 stages: RenderStages,
276 ) {
277 unsafe {
278 mtl_sys::msg_send_4::<(), *const *const c_void, UInteger, ResourceUsage, RenderStages>(
279 self.as_ptr(),
280 sel!(useResources: count: usage: stages:),
281 resources,
282 count,
283 usage,
284 stages,
285 );
286 }
287 }
288
289 // =========================================================================
290 // Fence Operations
291 // =========================================================================
292
293 /// Update a fence (raw pointer version).
294 ///
295 /// C++ equivalent: `void updateFence(const Fence*, MTL::RenderStages)`
296 ///
297 /// # Safety
298 ///
299 /// The fence pointer must be a valid Metal fence object.
300 #[inline]
301 pub unsafe fn update_fence_ptr(&self, fence: *const c_void, stages: RenderStages) {
302 unsafe {
303 mtl_sys::msg_send_2::<(), *const c_void, RenderStages>(
304 self.as_ptr(),
305 sel!(updateFence: afterStages:),
306 fence,
307 stages,
308 );
309 }
310 }
311
312 /// Update a fence.
313 ///
314 /// C++ equivalent: `void updateFence(const Fence*, MTL::RenderStages)`
315 #[inline]
316 pub fn update_fence(&self, fence: &crate::Fence, stages: RenderStages) {
317 unsafe { self.update_fence_ptr(fence.as_ptr(), stages) };
318 }
319
320 /// Wait for a fence (raw pointer version).
321 ///
322 /// C++ equivalent: `void waitForFence(const Fence*, MTL::RenderStages)`
323 ///
324 /// # Safety
325 ///
326 /// The fence pointer must be a valid Metal fence object.
327 #[inline]
328 pub unsafe fn wait_for_fence_ptr(&self, fence: *const c_void, stages: RenderStages) {
329 unsafe {
330 mtl_sys::msg_send_2::<(), *const c_void, RenderStages>(
331 self.as_ptr(),
332 sel!(waitForFence: beforeStages:),
333 fence,
334 stages,
335 );
336 }
337 }
338
339 /// Wait for a fence.
340 ///
341 /// C++ equivalent: `void waitForFence(const Fence*, MTL::RenderStages)`
342 #[inline]
343 pub fn wait_for_fence(&self, fence: &crate::Fence, stages: RenderStages) {
344 unsafe { self.wait_for_fence_ptr(fence.as_ptr(), stages) };
345 }
346
347 // =========================================================================
348 // Vertex Amplification
349 // =========================================================================
350
351 /// Set vertex amplification count.
352 ///
353 /// C++ equivalent: `void setVertexAmplificationCount(NS::UInteger, const VertexAmplificationViewMapping*)`
354 #[inline]
355 pub fn set_vertex_amplification_count(
356 &self,
357 count: UInteger,
358 view_mappings: Option<&[VertexAmplificationViewMapping]>,
359 ) {
360 let ptr = view_mappings
361 .map(|m| m.as_ptr())
362 .unwrap_or(std::ptr::null());
363 unsafe {
364 mtl_sys::msg_send_2::<(), UInteger, *const VertexAmplificationViewMapping>(
365 self.as_ptr(),
366 sel!(setVertexAmplificationCount: viewMappings:),
367 count,
368 ptr,
369 );
370 }
371 }
372
373 // =========================================================================
374 // Acceleration Structure Bindings
375 // =========================================================================
376
377 /// Set a vertex acceleration structure (raw pointer version).
378 ///
379 /// C++ equivalent: `void setVertexAccelerationStructure(const AccelerationStructure*, NS::UInteger)`
380 ///
381 /// # Safety
382 ///
383 /// The acceleration structure pointer must be valid.
384 #[inline]
385 pub unsafe fn set_vertex_acceleration_structure_ptr(
386 &self,
387 acceleration_structure: *const c_void,
388 buffer_index: UInteger,
389 ) {
390 unsafe {
391 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
392 self.as_ptr(),
393 sel!(setVertexAccelerationStructure: atBufferIndex:),
394 acceleration_structure,
395 buffer_index,
396 );
397 }
398 }
399
400 /// Set a vertex acceleration structure.
401 ///
402 /// C++ equivalent: `void setVertexAccelerationStructure(const AccelerationStructure*, NS::UInteger)`
403 #[inline]
404 pub fn set_vertex_acceleration_structure(
405 &self,
406 acceleration_structure: &crate::AccelerationStructure,
407 buffer_index: UInteger,
408 ) {
409 unsafe {
410 self.set_vertex_acceleration_structure_ptr(
411 acceleration_structure.as_ptr(),
412 buffer_index,
413 )
414 };
415 }
416
417 /// Set a fragment acceleration structure (raw pointer version).
418 ///
419 /// C++ equivalent: `void setFragmentAccelerationStructure(const AccelerationStructure*, NS::UInteger)`
420 ///
421 /// # Safety
422 ///
423 /// The acceleration structure pointer must be valid.
424 #[inline]
425 pub unsafe fn set_fragment_acceleration_structure_ptr(
426 &self,
427 acceleration_structure: *const c_void,
428 buffer_index: UInteger,
429 ) {
430 unsafe {
431 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
432 self.as_ptr(),
433 sel!(setFragmentAccelerationStructure: atBufferIndex:),
434 acceleration_structure,
435 buffer_index,
436 );
437 }
438 }
439
440 /// Set a fragment acceleration structure.
441 ///
442 /// C++ equivalent: `void setFragmentAccelerationStructure(const AccelerationStructure*, NS::UInteger)`
443 #[inline]
444 pub fn set_fragment_acceleration_structure(
445 &self,
446 acceleration_structure: &crate::AccelerationStructure,
447 buffer_index: UInteger,
448 ) {
449 unsafe {
450 self.set_fragment_acceleration_structure_ptr(
451 acceleration_structure.as_ptr(),
452 buffer_index,
453 )
454 };
455 }
456
457 /// Set a tile acceleration structure (raw pointer version).
458 ///
459 /// C++ equivalent: `void setTileAccelerationStructure(const AccelerationStructure*, NS::UInteger)`
460 ///
461 /// # Safety
462 ///
463 /// The acceleration structure pointer must be valid.
464 #[inline]
465 pub unsafe fn set_tile_acceleration_structure_ptr(
466 &self,
467 acceleration_structure: *const c_void,
468 buffer_index: UInteger,
469 ) {
470 unsafe {
471 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
472 self.as_ptr(),
473 sel!(setTileAccelerationStructure: atBufferIndex:),
474 acceleration_structure,
475 buffer_index,
476 );
477 }
478 }
479
480 /// Set a tile acceleration structure.
481 ///
482 /// C++ equivalent: `void setTileAccelerationStructure(const AccelerationStructure*, NS::UInteger)`
483 #[inline]
484 pub fn set_tile_acceleration_structure(
485 &self,
486 acceleration_structure: &crate::AccelerationStructure,
487 buffer_index: UInteger,
488 ) {
489 unsafe {
490 self.set_tile_acceleration_structure_ptr(acceleration_structure.as_ptr(), buffer_index)
491 };
492 }
493
494 // =========================================================================
495 // Function Table Bindings
496 // =========================================================================
497
498 /// Set a vertex visible function table (raw pointer version).
499 ///
500 /// C++ equivalent: `void setVertexVisibleFunctionTable(const VisibleFunctionTable*, NS::UInteger)`
501 ///
502 /// # Safety
503 ///
504 /// The function table pointer must be valid.
505 #[inline]
506 pub unsafe fn set_vertex_visible_function_table_ptr(
507 &self,
508 function_table: *const c_void,
509 buffer_index: UInteger,
510 ) {
511 unsafe {
512 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
513 self.as_ptr(),
514 sel!(setVertexVisibleFunctionTable: atBufferIndex:),
515 function_table,
516 buffer_index,
517 );
518 }
519 }
520
521 /// Set multiple vertex visible function tables (raw pointer version).
522 ///
523 /// C++ equivalent: `void setVertexVisibleFunctionTables(const VisibleFunctionTable* const*, NS::Range)`
524 ///
525 /// # Safety
526 ///
527 /// The function tables pointer must be a valid array with at least `range.length` elements.
528 #[inline]
529 pub unsafe fn set_vertex_visible_function_tables_ptr(
530 &self,
531 function_tables: *const *const c_void,
532 range_location: UInteger,
533 range_length: UInteger,
534 ) {
535 let range = mtl_foundation::Range::new(range_location, range_length);
536 unsafe {
537 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
538 self.as_ptr(),
539 sel!(setVertexVisibleFunctionTables: withBufferRange:),
540 function_tables,
541 range,
542 );
543 }
544 }
545
546 /// Set a vertex intersection function table (raw pointer version).
547 ///
548 /// C++ equivalent: `void setVertexIntersectionFunctionTable(const IntersectionFunctionTable*, NS::UInteger)`
549 ///
550 /// # Safety
551 ///
552 /// The function table pointer must be valid.
553 #[inline]
554 pub unsafe fn set_vertex_intersection_function_table_ptr(
555 &self,
556 function_table: *const c_void,
557 buffer_index: UInteger,
558 ) {
559 unsafe {
560 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
561 self.as_ptr(),
562 sel!(setVertexIntersectionFunctionTable: atBufferIndex:),
563 function_table,
564 buffer_index,
565 );
566 }
567 }
568
569 /// Set multiple vertex intersection function tables (raw pointer version).
570 ///
571 /// C++ equivalent: `void setVertexIntersectionFunctionTables(const IntersectionFunctionTable* const*, NS::Range)`
572 ///
573 /// # Safety
574 ///
575 /// The function tables pointer must be a valid array with at least `range.length` elements.
576 #[inline]
577 pub unsafe fn set_vertex_intersection_function_tables_ptr(
578 &self,
579 function_tables: *const *const c_void,
580 range_location: UInteger,
581 range_length: UInteger,
582 ) {
583 let range = mtl_foundation::Range::new(range_location, range_length);
584 unsafe {
585 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
586 self.as_ptr(),
587 sel!(setVertexIntersectionFunctionTables: withBufferRange:),
588 function_tables,
589 range,
590 );
591 }
592 }
593
594 /// Set a fragment visible function table (raw pointer version).
595 ///
596 /// C++ equivalent: `void setFragmentVisibleFunctionTable(const VisibleFunctionTable*, NS::UInteger)`
597 ///
598 /// # Safety
599 ///
600 /// The function table pointer must be valid.
601 #[inline]
602 pub unsafe fn set_fragment_visible_function_table_ptr(
603 &self,
604 function_table: *const c_void,
605 buffer_index: UInteger,
606 ) {
607 unsafe {
608 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
609 self.as_ptr(),
610 sel!(setFragmentVisibleFunctionTable: atBufferIndex:),
611 function_table,
612 buffer_index,
613 );
614 }
615 }
616
617 /// Set multiple fragment visible function tables (raw pointer version).
618 ///
619 /// C++ equivalent: `void setFragmentVisibleFunctionTables(const VisibleFunctionTable* const*, NS::Range)`
620 ///
621 /// # Safety
622 ///
623 /// The function tables pointer must be a valid array with at least `range.length` elements.
624 #[inline]
625 pub unsafe fn set_fragment_visible_function_tables_ptr(
626 &self,
627 function_tables: *const *const c_void,
628 range_location: UInteger,
629 range_length: UInteger,
630 ) {
631 let range = mtl_foundation::Range::new(range_location, range_length);
632 unsafe {
633 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
634 self.as_ptr(),
635 sel!(setFragmentVisibleFunctionTables: withBufferRange:),
636 function_tables,
637 range,
638 );
639 }
640 }
641
642 /// Set a fragment intersection function table (raw pointer version).
643 ///
644 /// C++ equivalent: `void setFragmentIntersectionFunctionTable(const IntersectionFunctionTable*, NS::UInteger)`
645 ///
646 /// # Safety
647 ///
648 /// The function table pointer must be valid.
649 #[inline]
650 pub unsafe fn set_fragment_intersection_function_table_ptr(
651 &self,
652 function_table: *const c_void,
653 buffer_index: UInteger,
654 ) {
655 unsafe {
656 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
657 self.as_ptr(),
658 sel!(setFragmentIntersectionFunctionTable: atBufferIndex:),
659 function_table,
660 buffer_index,
661 );
662 }
663 }
664
665 /// Set multiple fragment intersection function tables (raw pointer version).
666 ///
667 /// C++ equivalent: `void setFragmentIntersectionFunctionTables(const IntersectionFunctionTable* const*, NS::Range)`
668 ///
669 /// # Safety
670 ///
671 /// The function tables pointer must be a valid array with at least `range.length` elements.
672 #[inline]
673 pub unsafe fn set_fragment_intersection_function_tables_ptr(
674 &self,
675 function_tables: *const *const c_void,
676 range_location: UInteger,
677 range_length: UInteger,
678 ) {
679 let range = mtl_foundation::Range::new(range_location, range_length);
680 unsafe {
681 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
682 self.as_ptr(),
683 sel!(setFragmentIntersectionFunctionTables: withBufferRange:),
684 function_tables,
685 range,
686 );
687 }
688 }
689
690 /// Set a tile visible function table (raw pointer version).
691 ///
692 /// C++ equivalent: `void setTileVisibleFunctionTable(const VisibleFunctionTable*, NS::UInteger)`
693 ///
694 /// # Safety
695 ///
696 /// The function table pointer must be valid.
697 #[inline]
698 pub unsafe fn set_tile_visible_function_table_ptr(
699 &self,
700 function_table: *const c_void,
701 buffer_index: UInteger,
702 ) {
703 unsafe {
704 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
705 self.as_ptr(),
706 sel!(setTileVisibleFunctionTable: atBufferIndex:),
707 function_table,
708 buffer_index,
709 );
710 }
711 }
712
713 /// Set multiple tile visible function tables (raw pointer version).
714 ///
715 /// C++ equivalent: `void setTileVisibleFunctionTables(const VisibleFunctionTable* const*, NS::Range)`
716 ///
717 /// # Safety
718 ///
719 /// The function tables pointer must be a valid array with at least `range.length` elements.
720 #[inline]
721 pub unsafe fn set_tile_visible_function_tables_ptr(
722 &self,
723 function_tables: *const *const c_void,
724 range_location: UInteger,
725 range_length: UInteger,
726 ) {
727 let range = mtl_foundation::Range::new(range_location, range_length);
728 unsafe {
729 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
730 self.as_ptr(),
731 sel!(setTileVisibleFunctionTables: withBufferRange:),
732 function_tables,
733 range,
734 );
735 }
736 }
737
738 /// Set a tile intersection function table (raw pointer version).
739 ///
740 /// C++ equivalent: `void setTileIntersectionFunctionTable(const IntersectionFunctionTable*, NS::UInteger)`
741 ///
742 /// # Safety
743 ///
744 /// The function table pointer must be valid.
745 #[inline]
746 pub unsafe fn set_tile_intersection_function_table_ptr(
747 &self,
748 function_table: *const c_void,
749 buffer_index: UInteger,
750 ) {
751 unsafe {
752 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
753 self.as_ptr(),
754 sel!(setTileIntersectionFunctionTable: atBufferIndex:),
755 function_table,
756 buffer_index,
757 );
758 }
759 }
760
761 /// Set multiple tile intersection function tables (raw pointer version).
762 ///
763 /// C++ equivalent: `void setTileIntersectionFunctionTables(const IntersectionFunctionTable* const*, NS::Range)`
764 ///
765 /// # Safety
766 ///
767 /// The function tables pointer must be a valid array with at least `range.length` elements.
768 #[inline]
769 pub unsafe fn set_tile_intersection_function_tables_ptr(
770 &self,
771 function_tables: *const *const c_void,
772 range_location: UInteger,
773 range_length: UInteger,
774 ) {
775 let range = mtl_foundation::Range::new(range_location, range_length);
776 unsafe {
777 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
778 self.as_ptr(),
779 sel!(setTileIntersectionFunctionTables: withBufferRange:),
780 function_tables,
781 range,
782 );
783 }
784 }
785
786 // =========================================================================
787 // Indirect Command Execution
788 // =========================================================================
789
790 /// Execute commands from an indirect command buffer (raw pointer version).
791 ///
792 /// C++ equivalent: `void executeCommandsInBuffer(const IndirectCommandBuffer*, NS::Range)`
793 ///
794 /// # Safety
795 ///
796 /// The indirect command buffer pointer must be valid.
797 pub unsafe fn execute_commands_in_buffer_ptr(
798 &self,
799 indirect_command_buffer: *const c_void,
800 offset: UInteger,
801 length: UInteger,
802 ) {
803 let range = mtl_foundation::Range::new(offset, length);
804 unsafe {
805 mtl_sys::msg_send_2::<(), *const c_void, mtl_foundation::Range>(
806 self.as_ptr(),
807 sel!(executeCommandsInBuffer: withRange:),
808 indirect_command_buffer,
809 range,
810 );
811 }
812 }
813
814 /// Execute commands from an indirect command buffer with indirect range (raw pointer version).
815 ///
816 /// C++ equivalent: `void executeCommandsInBuffer(const IndirectCommandBuffer*, const Buffer*, NS::UInteger)`
817 ///
818 /// # Safety
819 ///
820 /// The indirect command buffer and range buffer pointers must be valid.
821 pub unsafe fn execute_commands_in_buffer_with_indirect_range_ptr(
822 &self,
823 indirect_command_buffer: *const c_void,
824 indirect_range_buffer: *const c_void,
825 indirect_buffer_offset: UInteger,
826 ) {
827 unsafe {
828 mtl_sys::msg_send_3::<(), *const c_void, *const c_void, UInteger>(
829 self.as_ptr(),
830 sel!(executeCommandsInBuffer: indirectBuffer: indirectBufferOffset:),
831 indirect_command_buffer,
832 indirect_range_buffer,
833 indirect_buffer_offset,
834 );
835 }
836 }
837
838 // =========================================================================
839 // Counter Sampling
840 // =========================================================================
841
842 /// Sample counters (raw pointer version).
843 ///
844 /// C++ equivalent: `void sampleCountersInBuffer(...)`
845 ///
846 /// # Safety
847 ///
848 /// The sample buffer pointer must be a valid counter sample buffer object.
849 pub unsafe fn sample_counters_in_buffer_ptr(
850 &self,
851 sample_buffer: *const c_void,
852 sample_index: UInteger,
853 barrier: bool,
854 ) {
855 unsafe {
856 mtl_sys::msg_send_3::<(), *const c_void, UInteger, bool>(
857 self.as_ptr(),
858 sel!(sampleCountersInBuffer: atSampleIndex: withBarrier:),
859 sample_buffer,
860 sample_index,
861 barrier,
862 );
863 }
864 }
865
866 // =========================================================================
867 // Color Attachment Map
868 // =========================================================================
869
870 /// Set the color attachment map (raw pointer version).
871 ///
872 /// C++ equivalent: `void setColorAttachmentMap(const LogicalToPhysicalColorAttachmentMap*)`
873 ///
874 /// # Safety
875 ///
876 /// The mapping pointer must be valid.
877 #[inline]
878 pub unsafe fn set_color_attachment_map_ptr(&self, mapping: *const c_void) {
879 unsafe {
880 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setColorAttachmentMap:), mapping);
881 }
882 }
883}