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}