Skip to main content

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}