Skip to main content

mtl_gpu/encoder/render_encoder/
tile.rs

1//! Tile shader bindings and properties.
2//!
3//! This module contains methods for binding resources to tile shaders
4//! and querying tile properties.
5
6use std::ffi::c_void;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::{msg_send_0, sel};
10
11use crate::Buffer;
12use crate::Texture;
13
14use super::RenderCommandEncoder;
15
16impl RenderCommandEncoder {
17    // =========================================================================
18    // Tile Bindings
19    // =========================================================================
20
21    /// Set a tile buffer.
22    ///
23    /// C++ equivalent: `void setTileBuffer(const Buffer*, NS::UInteger, NS::UInteger)`
24    #[inline]
25    pub fn set_tile_buffer(&self, buffer: &Buffer, offset: UInteger, index: UInteger) {
26        unsafe {
27            mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
28                self.as_ptr(),
29                sel!(setTileBuffer: offset: atIndex:),
30                buffer.as_ptr(),
31                offset,
32                index,
33            );
34        }
35    }
36
37    /// Set a tile texture.
38    ///
39    /// C++ equivalent: `void setTileTexture(const Texture*, NS::UInteger)`
40    #[inline]
41    pub fn set_tile_texture(&self, texture: &Texture, index: UInteger) {
42        unsafe {
43            mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
44                self.as_ptr(),
45                sel!(setTileTexture: atIndex:),
46                texture.as_ptr(),
47                index,
48            );
49        }
50    }
51
52    /// Set a tile sampler state.
53    ///
54    /// C++ equivalent: `void setTileSamplerState(const SamplerState*, NS::UInteger)`
55    #[inline]
56    pub fn set_tile_sampler_state(&self, sampler: &crate::SamplerState, index: UInteger) {
57        unsafe {
58            mtl_sys::msg_send_2::<(), *const c_void, UInteger>(
59                self.as_ptr(),
60                sel!(setTileSamplerState: atIndex:),
61                sampler.as_ptr(),
62                index,
63            );
64        }
65    }
66
67    /// Set inline tile bytes.
68    ///
69    /// C++ equivalent: `void setTileBytes(const void*, NS::UInteger, NS::UInteger)`
70    #[inline]
71    pub fn set_tile_bytes(&self, bytes: &[u8], index: UInteger) {
72        unsafe {
73            mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
74                self.as_ptr(),
75                sel!(setTileBytes: length: atIndex:),
76                bytes.as_ptr() as *const c_void,
77                bytes.len() as UInteger,
78                index,
79            );
80        }
81    }
82
83    /// Set the tile buffer offset.
84    ///
85    /// C++ equivalent: `void setTileBufferOffset(NS::UInteger, NS::UInteger)`
86    #[inline]
87    pub fn set_tile_buffer_offset(&self, offset: UInteger, index: UInteger) {
88        unsafe {
89            mtl_sys::msg_send_2::<(), UInteger, UInteger>(
90                self.as_ptr(),
91                sel!(setTileBufferOffset: atIndex:),
92                offset,
93                index,
94            );
95        }
96    }
97
98    /// Set multiple tile buffers at a range of indices (raw pointer version).
99    ///
100    /// C++ equivalent: `void setTileBuffers(const Buffer* const*, const NS::UInteger*, NS::Range)`
101    ///
102    /// # Safety
103    ///
104    /// The buffers and offsets pointers must be valid arrays with at least `range.length` elements.
105    #[inline]
106    pub unsafe fn set_tile_buffers_ptr(
107        &self,
108        buffers: *const *const c_void,
109        offsets: *const UInteger,
110        range_location: UInteger,
111        range_length: UInteger,
112    ) {
113        let range = mtl_foundation::Range::new(range_location, range_length);
114        unsafe {
115            mtl_sys::msg_send_3::<
116                (),
117                *const *const c_void,
118                *const UInteger,
119                mtl_foundation::Range,
120            >(
121                self.as_ptr(),
122                sel!(setTileBuffers: offsets: withRange:),
123                buffers,
124                offsets,
125                range,
126            );
127        }
128    }
129
130    /// Set multiple tile textures at a range of indices (raw pointer version).
131    ///
132    /// C++ equivalent: `void setTileTextures(const Texture* const*, NS::Range)`
133    ///
134    /// # Safety
135    ///
136    /// The textures pointer must be a valid array with at least `range.length` elements.
137    #[inline]
138    pub unsafe fn set_tile_textures_ptr(
139        &self,
140        textures: *const *const c_void,
141        range_location: UInteger,
142        range_length: UInteger,
143    ) {
144        let range = mtl_foundation::Range::new(range_location, range_length);
145        unsafe {
146            mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
147                self.as_ptr(),
148                sel!(setTileTextures: withRange:),
149                textures,
150                range,
151            );
152        }
153    }
154
155    /// Set a tile sampler state with LOD clamps.
156    ///
157    /// C++ equivalent: `void setTileSamplerState(const SamplerState*, float, float, NS::UInteger)`
158    #[inline]
159    pub fn set_tile_sampler_state_with_lod_clamps(
160        &self,
161        sampler: &crate::SamplerState,
162        lod_min_clamp: f32,
163        lod_max_clamp: f32,
164        index: UInteger,
165    ) {
166        unsafe {
167            mtl_sys::msg_send_4::<(), *const c_void, f32, f32, UInteger>(
168                self.as_ptr(),
169                sel!(setTileSamplerState: lodMinClamp: lodMaxClamp: atIndex:),
170                sampler.as_ptr(),
171                lod_min_clamp,
172                lod_max_clamp,
173                index,
174            );
175        }
176    }
177
178    /// Set multiple tile sampler states at a range of indices (raw pointer version).
179    ///
180    /// C++ equivalent: `void setTileSamplerStates(const SamplerState* const*, NS::Range)`
181    ///
182    /// # Safety
183    ///
184    /// The samplers pointer must be a valid array with at least `range.length` elements.
185    #[inline]
186    pub unsafe fn set_tile_sampler_states_ptr(
187        &self,
188        samplers: *const *const c_void,
189        range_location: UInteger,
190        range_length: UInteger,
191    ) {
192        let range = mtl_foundation::Range::new(range_location, range_length);
193        unsafe {
194            mtl_sys::msg_send_2::<(), *const *const c_void, mtl_foundation::Range>(
195                self.as_ptr(),
196                sel!(setTileSamplerStates: withRange:),
197                samplers,
198                range,
199            );
200        }
201    }
202
203    /// Set multiple tile sampler states with LOD clamps at a range of indices (raw pointer version).
204    ///
205    /// C++ equivalent: `void setTileSamplerStates(const SamplerState* const*, const float*, const float*, NS::Range)`
206    ///
207    /// # Safety
208    ///
209    /// The samplers, lod_min_clamps, and lod_max_clamps pointers must be valid arrays with at least `range.length` elements.
210    #[inline]
211    pub unsafe fn set_tile_sampler_states_with_lod_clamps_ptr(
212        &self,
213        samplers: *const *const c_void,
214        lod_min_clamps: *const f32,
215        lod_max_clamps: *const f32,
216        range_location: UInteger,
217        range_length: UInteger,
218    ) {
219        let range = mtl_foundation::Range::new(range_location, range_length);
220        unsafe {
221            mtl_sys::msg_send_4::<
222                (),
223                *const *const c_void,
224                *const f32,
225                *const f32,
226                mtl_foundation::Range,
227            >(
228                self.as_ptr(),
229                sel!(setTileSamplerStates: lodMinClamps: lodMaxClamps: withRange:),
230                samplers,
231                lod_min_clamps,
232                lod_max_clamps,
233                range,
234            );
235        }
236    }
237
238    // =========================================================================
239    // Tile Properties
240    // =========================================================================
241
242    /// Get the tile width.
243    ///
244    /// C++ equivalent: `NS::UInteger tileWidth() const`
245    #[inline]
246    pub fn tile_width(&self) -> UInteger {
247        unsafe { msg_send_0(self.as_ptr(), sel!(tileWidth)) }
248    }
249
250    /// Get the tile height.
251    ///
252    /// C++ equivalent: `NS::UInteger tileHeight() const`
253    #[inline]
254    pub fn tile_height(&self) -> UInteger {
255        unsafe { msg_send_0(self.as_ptr(), sel!(tileHeight)) }
256    }
257
258    // =========================================================================
259    // Threadgroup Memory
260    // =========================================================================
261
262    /// Set the threadgroup memory length at an index with offset.
263    ///
264    /// C++ equivalent: `void setThreadgroupMemoryLength(NS::UInteger, NS::UInteger, NS::UInteger)`
265    #[inline]
266    pub fn set_threadgroup_memory_length(
267        &self,
268        length: UInteger,
269        offset: UInteger,
270        index: UInteger,
271    ) {
272        unsafe {
273            mtl_sys::msg_send_3::<(), UInteger, UInteger, UInteger>(
274                self.as_ptr(),
275                sel!(setThreadgroupMemoryLength: offset: atIndex:),
276                length,
277                offset,
278                index,
279            );
280        }
281    }
282}