Skip to main content

mtl_gpu/encoder/compute_encoder/
binding.rs

1//! Resource binding methods for ComputeCommandEncoder.
2
3use std::ffi::c_void;
4
5use mtl_foundation::{Referencing, UInteger};
6use mtl_sys::sel;
7
8use crate::Buffer;
9use crate::Texture;
10
11use super::ComputeCommandEncoder;
12
13impl ComputeCommandEncoder {
14    // =========================================================================
15    // Buffer Bindings
16    // =========================================================================
17
18    /// Set a buffer at an index.
19    ///
20    /// C++ equivalent: `void setBuffer(const Buffer*, NS::UInteger, NS::UInteger)`
21    #[inline]
22    pub fn set_buffer(&self, buffer: &Buffer, offset: UInteger, index: UInteger) {
23        unsafe {
24            mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
25                self.as_ptr(),
26                sel!(setBuffer: offset: atIndex:),
27                buffer.as_ptr(),
28                offset,
29                index,
30            );
31        }
32    }
33
34    /// Set a buffer at an index with attribute stride.
35    ///
36    /// C++ equivalent: `void setBuffer(const Buffer*, NS::UInteger, NS::UInteger, NS::UInteger)`
37    #[inline]
38    pub fn set_buffer_with_stride(
39        &self,
40        buffer: &Buffer,
41        offset: UInteger,
42        stride: UInteger,
43        index: UInteger,
44    ) {
45        unsafe {
46            mtl_sys::msg_send_4::<(), *const c_void, UInteger, UInteger, UInteger>(
47                self.as_ptr(),
48                sel!(setBuffer: offset: attributeStride: atIndex:),
49                buffer.as_ptr(),
50                offset,
51                stride,
52                index,
53            );
54        }
55    }
56
57    /// Set the buffer offset at an index.
58    ///
59    /// C++ equivalent: `void setBufferOffset(NS::UInteger, NS::UInteger)`
60    #[inline]
61    pub fn set_buffer_offset(&self, offset: UInteger, index: UInteger) {
62        unsafe {
63            mtl_sys::msg_send_2::<(), UInteger, UInteger>(
64                self.as_ptr(),
65                sel!(setBufferOffset: atIndex:),
66                offset,
67                index,
68            );
69        }
70    }
71
72    /// Set the buffer offset at an index with attribute stride.
73    ///
74    /// C++ equivalent: `void setBufferOffset(NS::UInteger, NS::UInteger, NS::UInteger)`
75    #[inline]
76    pub fn set_buffer_offset_with_stride(
77        &self,
78        offset: UInteger,
79        stride: UInteger,
80        index: UInteger,
81    ) {
82        unsafe {
83            mtl_sys::msg_send_3::<(), UInteger, UInteger, UInteger>(
84                self.as_ptr(),
85                sel!(setBufferOffset: attributeStride: atIndex:),
86                offset,
87                stride,
88                index,
89            );
90        }
91    }
92
93    /// Set inline bytes at an index.
94    ///
95    /// C++ equivalent: `void setBytes(const void*, NS::UInteger, NS::UInteger)`
96    #[inline]
97    pub fn set_bytes(&self, bytes: &[u8], index: UInteger) {
98        unsafe {
99            mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
100                self.as_ptr(),
101                sel!(setBytes: length: atIndex:),
102                bytes.as_ptr() as *const c_void,
103                bytes.len() as UInteger,
104                index,
105            );
106        }
107    }
108
109    /// Set inline bytes at an index with attribute stride.
110    ///
111    /// C++ equivalent: `void setBytes(const void*, NS::UInteger, NS::UInteger, NS::UInteger)`
112    #[inline]
113    pub fn set_bytes_with_stride(&self, bytes: &[u8], stride: UInteger, index: UInteger) {
114        unsafe {
115            mtl_sys::msg_send_4::<(), *const c_void, UInteger, UInteger, UInteger>(
116                self.as_ptr(),
117                sel!(setBytes: length: attributeStride: atIndex:),
118                bytes.as_ptr() as *const c_void,
119                bytes.len() as UInteger,
120                stride,
121                index,
122            );
123        }
124    }
125
126    /// Set multiple buffers at a range of indices (raw pointer version).
127    ///
128    /// C++ equivalent: `void setBuffers(const Buffer* const*, const NS::UInteger*, NS::Range)`
129    ///
130    /// # Safety
131    ///
132    /// The buffers and offsets pointers must be valid arrays with at least `range.length` elements.
133    #[inline]
134    pub unsafe fn set_buffers_ptr(
135        &self,
136        buffers: *const *const c_void,
137        offsets: *const UInteger,
138        range_location: UInteger,
139        range_length: UInteger,
140    ) {
141        let range = mtl_foundation::Range::new(range_location, range_length);
142        unsafe {
143            mtl_sys::msg_send_3::<
144                (),
145                *const *const c_void,
146                *const UInteger,
147                mtl_foundation::Range,
148            >(
149                self.as_ptr(),
150                sel!(setBuffers: offsets: withRange:),
151                buffers,
152                offsets,
153                range,
154            );
155        }
156    }
157
158    /// Set multiple buffers at a range of indices with strides (raw pointer version).
159    ///
160    /// C++ equivalent: `void setBuffers(const Buffer* const*, const NS::UInteger*, const NS::UInteger*, NS::Range)`
161    ///
162    /// # Safety
163    ///
164    /// The buffers, offsets, and strides pointers must be valid arrays with at least `range.length` elements.
165    #[inline]
166    pub unsafe fn set_buffers_with_strides_ptr(
167        &self,
168        buffers: *const *const c_void,
169        offsets: *const UInteger,
170        strides: *const UInteger,
171        range_location: UInteger,
172        range_length: UInteger,
173    ) {
174        let range = mtl_foundation::Range::new(range_location, range_length);
175        unsafe {
176            mtl_sys::msg_send_4::<
177                (),
178                *const *const c_void,
179                *const UInteger,
180                *const UInteger,
181                mtl_foundation::Range,
182            >(
183                self.as_ptr(),
184                sel!(setBuffers: offsets: attributeStrides: withRange:),
185                buffers,
186                offsets,
187                strides,
188                range,
189            );
190        }
191    }
192
193    // =========================================================================
194    // Texture Bindings
195    // =========================================================================
196
197    /// Set a texture at an index.
198    ///
199    /// C++ equivalent: `void setTexture(const Texture*, NS::UInteger)`
200    #[inline]
201    pub fn set_texture(&self, texture: &Texture, index: UInteger) {
202        unsafe {
203            mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
204                self.as_ptr(),
205                sel!(setTexture: atIndex:),
206                texture.as_ptr(),
207                index,
208            );
209        }
210    }
211
212    /// Set multiple textures at a range of indices (raw pointer version).
213    ///
214    /// C++ equivalent: `void setTextures(const Texture* const*, NS::Range)`
215    ///
216    /// # Safety
217    ///
218    /// The textures pointer must be a valid array with at least `range.length` elements.
219    #[inline]
220    pub unsafe fn set_textures_ptr(
221        &self,
222        textures: *const *const c_void,
223        range_location: UInteger,
224        range_length: UInteger,
225    ) {
226        let range = mtl_foundation::Range::new(range_location, range_length);
227        unsafe {
228            mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
229                self.as_ptr(),
230                sel!(setTextures: withRange:),
231                textures,
232                range,
233            );
234        }
235    }
236
237    // =========================================================================
238    // Sampler Bindings
239    // =========================================================================
240
241    /// Set a sampler state at an index.
242    ///
243    /// C++ equivalent: `void setSamplerState(const SamplerState*, NS::UInteger)`
244    #[inline]
245    pub fn set_sampler_state(&self, sampler: &crate::SamplerState, index: UInteger) {
246        unsafe {
247            mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
248                self.as_ptr(),
249                sel!(setSamplerState: atIndex:),
250                sampler.as_ptr(),
251                index,
252            );
253        }
254    }
255
256    /// Set a sampler state with LOD clamps at an index.
257    ///
258    /// C++ equivalent: `void setSamplerState(const SamplerState*, float, float, NS::UInteger)`
259    #[inline]
260    pub fn set_sampler_state_with_lod_clamps(
261        &self,
262        sampler: &crate::SamplerState,
263        lod_min_clamp: f32,
264        lod_max_clamp: f32,
265        index: UInteger,
266    ) {
267        unsafe {
268            mtl_sys::msg_send_4::<(), *const c_void, f32, f32, UInteger>(
269                self.as_ptr(),
270                sel!(setSamplerState: lodMinClamp: lodMaxClamp: atIndex:),
271                sampler.as_ptr(),
272                lod_min_clamp,
273                lod_max_clamp,
274                index,
275            );
276        }
277    }
278
279    /// Set multiple sampler states at a range of indices (raw pointer version).
280    ///
281    /// C++ equivalent: `void setSamplerStates(const SamplerState* const*, NS::Range)`
282    ///
283    /// # Safety
284    ///
285    /// The samplers pointer must be a valid array with at least `range.length` elements.
286    #[inline]
287    pub unsafe fn set_sampler_states_ptr(
288        &self,
289        samplers: *const *const c_void,
290        range_location: UInteger,
291        range_length: UInteger,
292    ) {
293        let range = mtl_foundation::Range::new(range_location, range_length);
294        unsafe {
295            mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
296                self.as_ptr(),
297                sel!(setSamplerStates: withRange:),
298                samplers,
299                range,
300            );
301        }
302    }
303
304    /// Set multiple sampler states with LOD clamps at a range of indices (raw pointer version).
305    ///
306    /// C++ equivalent: `void setSamplerStates(const SamplerState* const*, const float*, const float*, NS::Range)`
307    ///
308    /// # Safety
309    ///
310    /// The samplers, lod_min_clamps, and lod_max_clamps pointers must be valid arrays with at least `range.length` elements.
311    #[inline]
312    pub unsafe fn set_sampler_states_with_lod_clamps_ptr(
313        &self,
314        samplers: *const *const c_void,
315        lod_min_clamps: *const f32,
316        lod_max_clamps: *const f32,
317        range_location: UInteger,
318        range_length: UInteger,
319    ) {
320        let range = mtl_foundation::Range::new(range_location, range_length);
321        unsafe {
322            mtl_sys::msg_send_4::<
323                (),
324                *const *const c_void,
325                *const f32,
326                *const f32,
327                mtl_foundation::Range,
328            >(
329                self.as_ptr(),
330                sel!(setSamplerStates: lodMinClamps: lodMaxClamps: withRange:),
331                samplers,
332                lod_min_clamps,
333                lod_max_clamps,
334                range,
335            );
336        }
337    }
338
339    // =========================================================================
340    // Threadgroup Memory
341    // =========================================================================
342
343    /// Set the threadgroup memory length at an index.
344    ///
345    /// C++ equivalent: `void setThreadgroupMemoryLength(NS::UInteger, NS::UInteger)`
346    #[inline]
347    pub fn set_threadgroup_memory_length(&self, length: UInteger, index: UInteger) {
348        unsafe {
349            mtl_sys::msg_send_2::<(), UInteger, UInteger>(
350                self.as_ptr(),
351                sel!(setThreadgroupMemoryLength: atIndex:),
352                length,
353                index,
354            );
355        }
356    }
357
358    /// Set the imageblock dimensions.
359    ///
360    /// C++ equivalent: `void setImageblockWidth(NS::UInteger, NS::UInteger)`
361    #[inline]
362    pub fn set_imageblock_width(&self, width: UInteger, height: UInteger) {
363        unsafe {
364            mtl_sys::msg_send_2::<(), UInteger, UInteger>(
365                self.as_ptr(),
366                sel!(setImageblockWidth: height:),
367                width,
368                height,
369            );
370        }
371    }
372}