mtl_gpu/encoder/compute_encoder/memory.rs
1//! Memory barrier and fence methods for ComputeCommandEncoder.
2
3use std::ffi::c_void;
4
5use mtl_foundation::{Referencing, UInteger};
6use mtl_sys::{msg_send_1, sel};
7
8use crate::Buffer;
9use crate::Texture;
10use crate::enums::{BarrierScope, ResourceUsage};
11
12use super::ComputeCommandEncoder;
13
14impl ComputeCommandEncoder {
15 // =========================================================================
16 // Memory Barriers
17 // =========================================================================
18
19 /// Insert a memory barrier with scope.
20 ///
21 /// C++ equivalent: `void memoryBarrier(MTL::BarrierScope)`
22 #[inline]
23 pub fn memory_barrier_with_scope(&self, scope: BarrierScope) {
24 unsafe {
25 msg_send_1::<(), BarrierScope>(self.as_ptr(), sel!(memoryBarrierWithScope:), scope);
26 }
27 }
28
29 /// Insert a memory barrier for specific resources (raw pointer version).
30 ///
31 /// C++ equivalent: `void memoryBarrier(const Resource* const*, NS::UInteger)`
32 ///
33 /// # Safety
34 ///
35 /// The resources pointer must point to a valid array of resource pointers with the specified count.
36 #[inline]
37 pub unsafe fn memory_barrier_with_resources_ptr(
38 &self,
39 resources: *const *const c_void,
40 count: UInteger,
41 ) {
42 unsafe {
43 mtl_sys::msg_send_2::<(), *const *const c_void, UInteger>(
44 self.as_ptr(),
45 sel!(memoryBarrierWithResources: count:),
46 resources,
47 count,
48 );
49 }
50 }
51
52 // =========================================================================
53 // Resource Usage
54 // =========================================================================
55
56 /// Declare that a resource will be used (raw pointer version).
57 ///
58 /// C++ equivalent: `void useResource(const Resource*, MTL::ResourceUsage)`
59 ///
60 /// # Safety
61 ///
62 /// The resource pointer must be a valid Metal resource object.
63 #[inline]
64 pub unsafe fn use_resource_ptr(&self, resource: *const c_void, usage: ResourceUsage) {
65 unsafe {
66 mtl_sys::msg_send_2::<(), *const c_void, ResourceUsage>(
67 self.as_ptr(),
68 sel!(useResource: usage:),
69 resource,
70 usage,
71 );
72 }
73 }
74
75 /// Declare that a buffer will be used.
76 ///
77 /// C++ equivalent: `void useResource(const Resource*, MTL::ResourceUsage)`
78 #[inline]
79 pub fn use_buffer(&self, buffer: &Buffer, usage: ResourceUsage) {
80 unsafe { self.use_resource_ptr(buffer.as_ptr(), usage) };
81 }
82
83 /// Declare that a texture will be used.
84 ///
85 /// C++ equivalent: `void useResource(const Resource*, MTL::ResourceUsage)`
86 #[inline]
87 pub fn use_texture(&self, texture: &Texture, usage: ResourceUsage) {
88 unsafe { self.use_resource_ptr(texture.as_ptr(), usage) };
89 }
90
91 /// Declare that a heap will be used (raw pointer version).
92 ///
93 /// C++ equivalent: `void useHeap(const Heap*)`
94 ///
95 /// # Safety
96 ///
97 /// The heap pointer must be a valid Metal heap object.
98 #[inline]
99 pub unsafe fn use_heap_ptr(&self, heap: *const c_void) {
100 unsafe {
101 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(useHeap:), heap);
102 }
103 }
104
105 /// Declare that a heap will be used.
106 ///
107 /// C++ equivalent: `void useHeap(const Heap*)`
108 #[inline]
109 pub fn use_heap(&self, heap: &crate::Heap) {
110 unsafe { self.use_heap_ptr(heap.as_ptr()) };
111 }
112
113 /// Declare that multiple heaps will be used (raw pointer version).
114 ///
115 /// C++ equivalent: `void useHeaps(const Heap* const*, NS::UInteger)`
116 ///
117 /// # Safety
118 ///
119 /// The heaps pointer must be a valid array of heap pointers with the specified count.
120 #[inline]
121 pub unsafe fn use_heaps_ptr(&self, heaps: *const *const c_void, count: UInteger) {
122 unsafe {
123 mtl_sys::msg_send_2::<(), *const *const c_void, UInteger>(
124 self.as_ptr(),
125 sel!(useHeaps: count:),
126 heaps,
127 count,
128 );
129 }
130 }
131
132 /// Declare that multiple resources will be used (raw pointer version).
133 ///
134 /// C++ equivalent: `void useResources(const Resource* const*, NS::UInteger, MTL::ResourceUsage)`
135 ///
136 /// # Safety
137 ///
138 /// The resources pointer must be a valid array of resource pointers with the specified count.
139 #[inline]
140 pub unsafe fn use_resources_ptr(
141 &self,
142 resources: *const *const c_void,
143 count: UInteger,
144 usage: ResourceUsage,
145 ) {
146 unsafe {
147 mtl_sys::msg_send_3::<(), *const *const c_void, UInteger, ResourceUsage>(
148 self.as_ptr(),
149 sel!(useResources: count: usage:),
150 resources,
151 count,
152 usage,
153 );
154 }
155 }
156
157 // =========================================================================
158 // Fence Operations
159 // =========================================================================
160
161 /// Update a fence (raw pointer version).
162 ///
163 /// C++ equivalent: `void updateFence(const Fence*)`
164 ///
165 /// # Safety
166 ///
167 /// The fence pointer must be a valid Metal fence object.
168 #[inline]
169 pub unsafe fn update_fence_ptr(&self, fence: *const c_void) {
170 unsafe {
171 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(updateFence:), fence);
172 }
173 }
174
175 /// Update a fence.
176 ///
177 /// C++ equivalent: `void updateFence(const Fence*)`
178 #[inline]
179 pub fn update_fence(&self, fence: &crate::Fence) {
180 unsafe { self.update_fence_ptr(fence.as_ptr()) };
181 }
182
183 /// Wait for a fence (raw pointer version).
184 ///
185 /// C++ equivalent: `void waitForFence(const Fence*)`
186 ///
187 /// # Safety
188 ///
189 /// The fence pointer must be a valid Metal fence object.
190 #[inline]
191 pub unsafe fn wait_for_fence_ptr(&self, fence: *const c_void) {
192 unsafe {
193 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(waitForFence:), fence);
194 }
195 }
196
197 /// Wait for a fence.
198 ///
199 /// C++ equivalent: `void waitForFence(const Fence*)`
200 #[inline]
201 pub fn wait_for_fence(&self, fence: &crate::Fence) {
202 unsafe { self.wait_for_fence_ptr(fence.as_ptr()) };
203 }
204}