mtl_gpu/encoder/render_encoder/binding.rs
1//! Resource binding methods for vertex and fragment stages.
2//!
3//! This module contains methods for binding buffers, textures, and samplers
4//! to both vertex and fragment shader stages.
5
6use std::ffi::c_void;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::sel;
10
11use crate::Buffer;
12use crate::Texture;
13
14use super::RenderCommandEncoder;
15
16impl RenderCommandEncoder {
17 // Vertex Buffers
18 // =========================================================================
19
20 /// Set a vertex buffer.
21 ///
22 /// C++ equivalent: `void setVertexBuffer(const Buffer*, NS::UInteger, NS::UInteger)`
23 #[inline]
24 pub fn set_vertex_buffer(&self, buffer: &Buffer, offset: UInteger, index: UInteger) {
25 unsafe {
26 mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
27 self.as_ptr(),
28 sel!(setVertexBuffer: offset: atIndex:),
29 buffer.as_ptr(),
30 offset,
31 index,
32 );
33 }
34 }
35
36 /// Set a vertex buffer with attribute stride.
37 ///
38 /// C++ equivalent: `void setVertexBuffer(const Buffer*, NS::UInteger, NS::UInteger, NS::UInteger)`
39 #[inline]
40 pub fn set_vertex_buffer_with_stride(
41 &self,
42 buffer: &Buffer,
43 offset: UInteger,
44 stride: UInteger,
45 index: UInteger,
46 ) {
47 unsafe {
48 mtl_sys::msg_send_4::<(), *const c_void, UInteger, UInteger, UInteger>(
49 self.as_ptr(),
50 sel!(setVertexBuffer: offset: attributeStride: atIndex:),
51 buffer.as_ptr(),
52 offset,
53 stride,
54 index,
55 );
56 }
57 }
58
59 /// Set the vertex buffer offset.
60 ///
61 /// C++ equivalent: `void setVertexBufferOffset(NS::UInteger, NS::UInteger)`
62 #[inline]
63 pub fn set_vertex_buffer_offset(&self, offset: UInteger, index: UInteger) {
64 unsafe {
65 mtl_sys::msg_send_2::<(), UInteger, UInteger>(
66 self.as_ptr(),
67 sel!(setVertexBufferOffset: atIndex:),
68 offset,
69 index,
70 );
71 }
72 }
73
74 /// Set inline vertex bytes.
75 ///
76 /// C++ equivalent: `void setVertexBytes(const void*, NS::UInteger, NS::UInteger)`
77 #[inline]
78 pub fn set_vertex_bytes(&self, bytes: &[u8], index: UInteger) {
79 unsafe {
80 mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
81 self.as_ptr(),
82 sel!(setVertexBytes: length: atIndex:),
83 bytes.as_ptr() as *const c_void,
84 bytes.len() as UInteger,
85 index,
86 );
87 }
88 }
89
90 /// Set inline vertex bytes with attribute stride.
91 ///
92 /// C++ equivalent: `void setVertexBytes(const void*, NS::UInteger, NS::UInteger, NS::UInteger)`
93 #[inline]
94 pub fn set_vertex_bytes_with_stride(&self, bytes: &[u8], stride: UInteger, index: UInteger) {
95 unsafe {
96 mtl_sys::msg_send_4::<(), *const c_void, UInteger, UInteger, UInteger>(
97 self.as_ptr(),
98 sel!(setVertexBytes: length: attributeStride: atIndex:),
99 bytes.as_ptr() as *const c_void,
100 bytes.len() as UInteger,
101 stride,
102 index,
103 );
104 }
105 }
106
107 /// Set the vertex buffer offset with attribute stride.
108 ///
109 /// C++ equivalent: `void setVertexBufferOffset(NS::UInteger, NS::UInteger, NS::UInteger)`
110 #[inline]
111 pub fn set_vertex_buffer_offset_with_stride(
112 &self,
113 offset: UInteger,
114 stride: UInteger,
115 index: UInteger,
116 ) {
117 unsafe {
118 mtl_sys::msg_send_3::<(), UInteger, UInteger, UInteger>(
119 self.as_ptr(),
120 sel!(setVertexBufferOffset: attributeStride: atIndex:),
121 offset,
122 stride,
123 index,
124 );
125 }
126 }
127
128 /// Set multiple vertex buffers at a range of indices (raw pointer version).
129 ///
130 /// C++ equivalent: `void setVertexBuffers(const Buffer* const*, const NS::UInteger*, NS::Range)`
131 ///
132 /// # Safety
133 ///
134 /// The buffers and offsets pointers must be valid arrays with at least `range.length` elements.
135 #[inline]
136 pub unsafe fn set_vertex_buffers_ptr(
137 &self,
138 buffers: *const *const c_void,
139 offsets: *const UInteger,
140 range_location: UInteger,
141 range_length: UInteger,
142 ) {
143 let range = mtl_foundation::Range::new(range_location, range_length);
144 unsafe {
145 mtl_sys::msg_send_3::<
146 (),
147 *const *const c_void,
148 *const UInteger,
149 mtl_foundation::Range,
150 >(
151 self.as_ptr(),
152 sel!(setVertexBuffers: offsets: withRange:),
153 buffers,
154 offsets,
155 range,
156 );
157 }
158 }
159
160 /// Set multiple vertex buffers with strides at a range of indices (raw pointer version).
161 ///
162 /// C++ equivalent: `void setVertexBuffers(const Buffer* const*, const NS::UInteger*, const NS::UInteger*, NS::Range)`
163 ///
164 /// # Safety
165 ///
166 /// The buffers, offsets, and strides pointers must be valid arrays with at least `range.length` elements.
167 #[inline]
168 pub unsafe fn set_vertex_buffers_with_strides_ptr(
169 &self,
170 buffers: *const *const c_void,
171 offsets: *const UInteger,
172 strides: *const UInteger,
173 range_location: UInteger,
174 range_length: UInteger,
175 ) {
176 let range = mtl_foundation::Range::new(range_location, range_length);
177 unsafe {
178 mtl_sys::msg_send_4::<
179 (),
180 *const *const c_void,
181 *const UInteger,
182 *const UInteger,
183 mtl_foundation::Range,
184 >(
185 self.as_ptr(),
186 sel!(setVertexBuffers: offsets: attributeStrides: withRange:),
187 buffers,
188 offsets,
189 strides,
190 range,
191 );
192 }
193 }
194
195 // =========================================================================
196 // Vertex Textures
197 // =========================================================================
198
199 /// Set a vertex texture.
200 ///
201 /// C++ equivalent: `void setVertexTexture(const Texture*, NS::UInteger)`
202 #[inline]
203 pub fn set_vertex_texture(&self, texture: &Texture, index: UInteger) {
204 unsafe {
205 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
206 self.as_ptr(),
207 sel!(setVertexTexture: atIndex:),
208 texture.as_ptr(),
209 index,
210 );
211 }
212 }
213
214 /// Set multiple vertex textures at a range of indices (raw pointer version).
215 ///
216 /// C++ equivalent: `void setVertexTextures(const Texture* const*, NS::Range)`
217 ///
218 /// # Safety
219 ///
220 /// The textures pointer must be a valid array with at least `range.length` elements.
221 #[inline]
222 pub unsafe fn set_vertex_textures_ptr(
223 &self,
224 textures: *const *const c_void,
225 range_location: UInteger,
226 range_length: UInteger,
227 ) {
228 let range = mtl_foundation::Range::new(range_location, range_length);
229 unsafe {
230 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
231 self.as_ptr(),
232 sel!(setVertexTextures: withRange:),
233 textures,
234 range,
235 );
236 }
237 }
238
239 // =========================================================================
240 // Vertex Samplers
241 // =========================================================================
242
243 /// Set a vertex sampler state.
244 ///
245 /// C++ equivalent: `void setVertexSamplerState(const SamplerState*, NS::UInteger)`
246 #[inline]
247 pub fn set_vertex_sampler_state(&self, sampler: &crate::SamplerState, index: UInteger) {
248 unsafe {
249 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
250 self.as_ptr(),
251 sel!(setVertexSamplerState: atIndex:),
252 sampler.as_ptr(),
253 index,
254 );
255 }
256 }
257
258 /// Set a vertex sampler state with LOD clamps.
259 ///
260 /// C++ equivalent: `void setVertexSamplerState(const SamplerState*, float, float, NS::UInteger)`
261 #[inline]
262 pub fn set_vertex_sampler_state_with_lod_clamps(
263 &self,
264 sampler: &crate::SamplerState,
265 lod_min_clamp: f32,
266 lod_max_clamp: f32,
267 index: UInteger,
268 ) {
269 unsafe {
270 mtl_sys::msg_send_4::<(), *const c_void, f32, f32, UInteger>(
271 self.as_ptr(),
272 sel!(setVertexSamplerState: lodMinClamp: lodMaxClamp: atIndex:),
273 sampler.as_ptr(),
274 lod_min_clamp,
275 lod_max_clamp,
276 index,
277 );
278 }
279 }
280
281 /// Set multiple vertex sampler states at a range of indices (raw pointer version).
282 ///
283 /// C++ equivalent: `void setVertexSamplerStates(const SamplerState* const*, NS::Range)`
284 ///
285 /// # Safety
286 ///
287 /// The samplers pointer must be a valid array with at least `range.length` elements.
288 #[inline]
289 pub unsafe fn set_vertex_sampler_states_ptr(
290 &self,
291 samplers: *const *const c_void,
292 range_location: UInteger,
293 range_length: UInteger,
294 ) {
295 let range = mtl_foundation::Range::new(range_location, range_length);
296 unsafe {
297 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
298 self.as_ptr(),
299 sel!(setVertexSamplerStates: withRange:),
300 samplers,
301 range,
302 );
303 }
304 }
305
306 /// Set multiple vertex sampler states with LOD clamps at a range of indices (raw pointer version).
307 ///
308 /// C++ equivalent: `void setVertexSamplerStates(const SamplerState* const*, const float*, const float*, NS::Range)`
309 ///
310 /// # Safety
311 ///
312 /// The samplers, lod_min_clamps, and lod_max_clamps pointers must be valid arrays with at least `range.length` elements.
313 #[inline]
314 pub unsafe fn set_vertex_sampler_states_with_lod_clamps_ptr(
315 &self,
316 samplers: *const *const c_void,
317 lod_min_clamps: *const f32,
318 lod_max_clamps: *const f32,
319 range_location: UInteger,
320 range_length: UInteger,
321 ) {
322 let range = mtl_foundation::Range::new(range_location, range_length);
323 unsafe {
324 mtl_sys::msg_send_4::<
325 (),
326 *const *const c_void,
327 *const f32,
328 *const f32,
329 mtl_foundation::Range,
330 >(
331 self.as_ptr(),
332 sel!(setVertexSamplerStates: lodMinClamps: lodMaxClamps: withRange:),
333 samplers,
334 lod_min_clamps,
335 lod_max_clamps,
336 range,
337 );
338 }
339 }
340
341 // =========================================================================
342 // Fragment Buffers
343 // =========================================================================
344
345 /// Set a fragment buffer.
346 ///
347 /// C++ equivalent: `void setFragmentBuffer(const Buffer*, NS::UInteger, NS::UInteger)`
348 #[inline]
349 pub fn set_fragment_buffer(&self, buffer: &Buffer, offset: UInteger, index: UInteger) {
350 unsafe {
351 mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
352 self.as_ptr(),
353 sel!(setFragmentBuffer: offset: atIndex:),
354 buffer.as_ptr(),
355 offset,
356 index,
357 );
358 }
359 }
360
361 /// Set the fragment buffer offset.
362 ///
363 /// C++ equivalent: `void setFragmentBufferOffset(NS::UInteger, NS::UInteger)`
364 #[inline]
365 pub fn set_fragment_buffer_offset(&self, offset: UInteger, index: UInteger) {
366 unsafe {
367 mtl_sys::msg_send_2::<(), UInteger, UInteger>(
368 self.as_ptr(),
369 sel!(setFragmentBufferOffset: atIndex:),
370 offset,
371 index,
372 );
373 }
374 }
375
376 /// Set inline fragment bytes.
377 ///
378 /// C++ equivalent: `void setFragmentBytes(const void*, NS::UInteger, NS::UInteger)`
379 #[inline]
380 pub fn set_fragment_bytes(&self, bytes: &[u8], index: UInteger) {
381 unsafe {
382 mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
383 self.as_ptr(),
384 sel!(setFragmentBytes: length: atIndex:),
385 bytes.as_ptr() as *const c_void,
386 bytes.len() as UInteger,
387 index,
388 );
389 }
390 }
391
392 /// Set multiple fragment buffers at a range of indices (raw pointer version).
393 ///
394 /// C++ equivalent: `void setFragmentBuffers(const Buffer* const*, const NS::UInteger*, NS::Range)`
395 ///
396 /// # Safety
397 ///
398 /// The buffers and offsets pointers must be valid arrays with at least `range.length` elements.
399 #[inline]
400 pub unsafe fn set_fragment_buffers_ptr(
401 &self,
402 buffers: *const *const c_void,
403 offsets: *const UInteger,
404 range_location: UInteger,
405 range_length: UInteger,
406 ) {
407 let range = mtl_foundation::Range::new(range_location, range_length);
408 unsafe {
409 mtl_sys::msg_send_3::<
410 (),
411 *const *const c_void,
412 *const UInteger,
413 mtl_foundation::Range,
414 >(
415 self.as_ptr(),
416 sel!(setFragmentBuffers: offsets: withRange:),
417 buffers,
418 offsets,
419 range,
420 );
421 }
422 }
423
424 // =========================================================================
425 // Fragment Textures
426 // =========================================================================
427
428 /// Set a fragment texture.
429 ///
430 /// C++ equivalent: `void setFragmentTexture(const Texture*, NS::UInteger)`
431 #[inline]
432 pub fn set_fragment_texture(&self, texture: &Texture, index: UInteger) {
433 unsafe {
434 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
435 self.as_ptr(),
436 sel!(setFragmentTexture: atIndex:),
437 texture.as_ptr(),
438 index,
439 );
440 }
441 }
442
443 /// Set multiple fragment textures at a range of indices (raw pointer version).
444 ///
445 /// C++ equivalent: `void setFragmentTextures(const Texture* const*, NS::Range)`
446 ///
447 /// # Safety
448 ///
449 /// The textures pointer must be a valid array with at least `range.length` elements.
450 #[inline]
451 pub unsafe fn set_fragment_textures_ptr(
452 &self,
453 textures: *const *const c_void,
454 range_location: UInteger,
455 range_length: UInteger,
456 ) {
457 let range = mtl_foundation::Range::new(range_location, range_length);
458 unsafe {
459 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
460 self.as_ptr(),
461 sel!(setFragmentTextures: withRange:),
462 textures,
463 range,
464 );
465 }
466 }
467
468 // =========================================================================
469 // Fragment Samplers
470 // =========================================================================
471
472 /// Set a fragment sampler state.
473 ///
474 /// C++ equivalent: `void setFragmentSamplerState(const SamplerState*, NS::UInteger)`
475 #[inline]
476 pub fn set_fragment_sampler_state(&self, sampler: &crate::SamplerState, index: UInteger) {
477 unsafe {
478 mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
479 self.as_ptr(),
480 sel!(setFragmentSamplerState: atIndex:),
481 sampler.as_ptr(),
482 index,
483 );
484 }
485 }
486
487 /// Set a fragment sampler state with LOD clamps.
488 ///
489 /// C++ equivalent: `void setFragmentSamplerState(const SamplerState*, float, float, NS::UInteger)`
490 #[inline]
491 pub fn set_fragment_sampler_state_with_lod_clamps(
492 &self,
493 sampler: &crate::SamplerState,
494 lod_min_clamp: f32,
495 lod_max_clamp: f32,
496 index: UInteger,
497 ) {
498 unsafe {
499 mtl_sys::msg_send_4::<(), *const c_void, f32, f32, UInteger>(
500 self.as_ptr(),
501 sel!(setFragmentSamplerState: lodMinClamp: lodMaxClamp: atIndex:),
502 sampler.as_ptr(),
503 lod_min_clamp,
504 lod_max_clamp,
505 index,
506 );
507 }
508 }
509
510 /// Set multiple fragment sampler states at a range of indices (raw pointer version).
511 ///
512 /// C++ equivalent: `void setFragmentSamplerStates(const SamplerState* const*, NS::Range)`
513 ///
514 /// # Safety
515 ///
516 /// The samplers pointer must be a valid array with at least `range.length` elements.
517 #[inline]
518 pub unsafe fn set_fragment_sampler_states_ptr(
519 &self,
520 samplers: *const *const c_void,
521 range_location: UInteger,
522 range_length: UInteger,
523 ) {
524 let range = mtl_foundation::Range::new(range_location, range_length);
525 unsafe {
526 mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
527 self.as_ptr(),
528 sel!(setFragmentSamplerStates: withRange:),
529 samplers,
530 range,
531 );
532 }
533 }
534
535 /// Set multiple fragment sampler states with LOD clamps at a range of indices (raw pointer version).
536 ///
537 /// C++ equivalent: `void setFragmentSamplerStates(const SamplerState* const*, const float*, const float*, NS::Range)`
538 ///
539 /// # Safety
540 ///
541 /// The samplers, lod_min_clamps, and lod_max_clamps pointers must be valid arrays with at least `range.length` elements.
542 #[inline]
543 pub unsafe fn set_fragment_sampler_states_with_lod_clamps_ptr(
544 &self,
545 samplers: *const *const c_void,
546 lod_min_clamps: *const f32,
547 lod_max_clamps: *const f32,
548 range_location: UInteger,
549 range_length: UInteger,
550 ) {
551 let range = mtl_foundation::Range::new(range_location, range_length);
552 unsafe {
553 mtl_sys::msg_send_4::<
554 (),
555 *const *const c_void,
556 *const f32,
557 *const f32,
558 mtl_foundation::Range,
559 >(
560 self.as_ptr(),
561 sel!(setFragmentSamplerStates: lodMinClamps: lodMaxClamps: withRange:),
562 samplers,
563 lod_min_clamps,
564 lod_max_clamps,
565 range,
566 );
567 }
568 }
569
570 // =========================================================================
571}