Skip to main content

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}