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}