1use std::ffi::c_void;
7
8use mtl_foundation::{Integer, Referencing, UInteger};
9use mtl_sys::{msg_send_1, sel};
10
11use crate::Buffer;
12use crate::enums::{IndexType, PrimitiveType};
13use crate::types::Size;
14
15use super::RenderCommandEncoder;
16
17impl RenderCommandEncoder {
18 #[inline]
26 pub fn draw_primitives(
27 &self,
28 primitive_type: PrimitiveType,
29 vertex_start: UInteger,
30 vertex_count: UInteger,
31 ) {
32 unsafe {
33 mtl_sys::msg_send_3::<(), PrimitiveType, UInteger, UInteger>(
34 self.as_ptr(),
35 sel!(drawPrimitives: vertexStart: vertexCount:),
36 primitive_type,
37 vertex_start,
38 vertex_count,
39 );
40 }
41 }
42
43 #[inline]
47 pub fn draw_primitives_instanced(
48 &self,
49 primitive_type: PrimitiveType,
50 vertex_start: UInteger,
51 vertex_count: UInteger,
52 instance_count: UInteger,
53 ) {
54 unsafe {
55 mtl_sys::msg_send_4::<(), PrimitiveType, UInteger, UInteger, UInteger>(
56 self.as_ptr(),
57 sel!(drawPrimitives: vertexStart: vertexCount: instanceCount:),
58 primitive_type,
59 vertex_start,
60 vertex_count,
61 instance_count,
62 );
63 }
64 }
65
66 #[inline]
70 pub fn draw_primitives_instanced_base_instance(
71 &self,
72 primitive_type: PrimitiveType,
73 vertex_start: UInteger,
74 vertex_count: UInteger,
75 instance_count: UInteger,
76 base_instance: UInteger,
77 ) {
78 unsafe {
79 mtl_sys::msg_send_5::<(), PrimitiveType, UInteger, UInteger, UInteger, UInteger>(
80 self.as_ptr(),
81 sel!(drawPrimitives: vertexStart: vertexCount: instanceCount: baseInstance:),
82 primitive_type,
83 vertex_start,
84 vertex_count,
85 instance_count,
86 base_instance,
87 );
88 }
89 }
90
91 #[inline]
95 pub fn draw_primitives_indirect(
96 &self,
97 primitive_type: PrimitiveType,
98 indirect_buffer: &Buffer,
99 indirect_buffer_offset: UInteger,
100 ) {
101 unsafe {
102 mtl_sys::msg_send_3::<(), PrimitiveType, *const c_void, UInteger>(
103 self.as_ptr(),
104 sel!(drawPrimitives: indirectBuffer: indirectBufferOffset:),
105 primitive_type,
106 indirect_buffer.as_ptr(),
107 indirect_buffer_offset,
108 );
109 }
110 }
111
112 #[inline]
120 pub fn draw_indexed_primitives(
121 &self,
122 primitive_type: PrimitiveType,
123 index_count: UInteger,
124 index_type: IndexType,
125 index_buffer: &Buffer,
126 index_buffer_offset: UInteger,
127 ) {
128 unsafe {
129 mtl_sys::msg_send_5::<(), PrimitiveType, UInteger, IndexType, *const c_void, UInteger>(
130 self.as_ptr(),
131 sel!(drawIndexedPrimitives: indexCount: indexType: indexBuffer: indexBufferOffset:),
132 primitive_type,
133 index_count,
134 index_type,
135 index_buffer.as_ptr(),
136 index_buffer_offset,
137 );
138 }
139 }
140
141 #[inline]
145 pub fn draw_indexed_primitives_instanced(
146 &self,
147 primitive_type: PrimitiveType,
148 index_count: UInteger,
149 index_type: IndexType,
150 index_buffer: &Buffer,
151 index_buffer_offset: UInteger,
152 instance_count: UInteger,
153 ) {
154 unsafe {
155 mtl_sys::msg_send_6::<
156 (),
157 PrimitiveType,
158 UInteger,
159 IndexType,
160 *const c_void,
161 UInteger,
162 UInteger,
163 >(
164 self.as_ptr(),
165 sel!(drawIndexedPrimitives: indexCount: indexType: indexBuffer: indexBufferOffset: instanceCount:),
166 primitive_type,
167 index_count,
168 index_type,
169 index_buffer.as_ptr(),
170 index_buffer_offset,
171 instance_count,
172 );
173 }
174 }
175
176 #[allow(clippy::too_many_arguments)]
180 #[inline]
181 pub fn draw_indexed_primitives_instanced_base_vertex_base_instance(
182 &self,
183 primitive_type: PrimitiveType,
184 index_count: UInteger,
185 index_type: IndexType,
186 index_buffer: &Buffer,
187 index_buffer_offset: UInteger,
188 instance_count: UInteger,
189 base_vertex: Integer,
190 base_instance: UInteger,
191 ) {
192 unsafe {
193 mtl_sys::msg_send_8::<
194 (),
195 PrimitiveType,
196 UInteger,
197 IndexType,
198 *const c_void,
199 UInteger,
200 UInteger,
201 Integer,
202 UInteger,
203 >(
204 self.as_ptr(),
205 sel!(drawIndexedPrimitives: indexCount: indexType: indexBuffer: indexBufferOffset: instanceCount: baseVertex: baseInstance:),
206 primitive_type,
207 index_count,
208 index_type,
209 index_buffer.as_ptr(),
210 index_buffer_offset,
211 instance_count,
212 base_vertex,
213 base_instance,
214 );
215 }
216 }
217
218 #[inline]
222 pub fn draw_indexed_primitives_indirect(
223 &self,
224 primitive_type: PrimitiveType,
225 index_type: IndexType,
226 index_buffer: &Buffer,
227 index_buffer_offset: UInteger,
228 indirect_buffer: &Buffer,
229 indirect_buffer_offset: UInteger,
230 ) {
231 unsafe {
232 mtl_sys::msg_send_6::<
233 (),
234 PrimitiveType,
235 IndexType,
236 *const c_void,
237 UInteger,
238 *const c_void,
239 UInteger,
240 >(
241 self.as_ptr(),
242 sel!(drawIndexedPrimitives: indexType: indexBuffer: indexBufferOffset: indirectBuffer: indirectBufferOffset:),
243 primitive_type,
244 index_type,
245 index_buffer.as_ptr(),
246 index_buffer_offset,
247 indirect_buffer.as_ptr(),
248 indirect_buffer_offset,
249 );
250 }
251 }
252
253 #[inline]
261 pub fn set_tessellation_factor_buffer(
262 &self,
263 buffer: &Buffer,
264 offset: UInteger,
265 instance_stride: UInteger,
266 ) {
267 unsafe {
268 mtl_sys::msg_send_3::<(), *const c_void, UInteger, UInteger>(
269 self.as_ptr(),
270 sel!(setTessellationFactorBuffer: offset: instanceStride:),
271 buffer.as_ptr(),
272 offset,
273 instance_stride,
274 );
275 }
276 }
277
278 #[inline]
282 pub fn set_tessellation_factor_scale(&self, scale: f32) {
283 unsafe {
284 msg_send_1::<(), f32>(self.as_ptr(), sel!(setTessellationFactorScale:), scale);
285 }
286 }
287
288 #[allow(clippy::too_many_arguments)]
292 pub fn draw_patches(
293 &self,
294 number_of_patch_control_points: UInteger,
295 patch_start: UInteger,
296 patch_count: UInteger,
297 patch_index_buffer: Option<&Buffer>,
298 patch_index_buffer_offset: UInteger,
299 instance_count: UInteger,
300 base_instance: UInteger,
301 ) {
302 let patch_index_buffer_ptr = patch_index_buffer
303 .map(|b| b.as_ptr())
304 .unwrap_or(std::ptr::null());
305 unsafe {
306 mtl_sys::msg_send_7::<
307 (),
308 UInteger,
309 UInteger,
310 UInteger,
311 *const c_void,
312 UInteger,
313 UInteger,
314 UInteger,
315 >(
316 self.as_ptr(),
317 sel!(drawPatches: patchStart: patchCount: patchIndexBuffer: patchIndexBufferOffset: instanceCount: baseInstance:),
318 number_of_patch_control_points,
319 patch_start,
320 patch_count,
321 patch_index_buffer_ptr,
322 patch_index_buffer_offset,
323 instance_count,
324 base_instance,
325 );
326 }
327 }
328
329 #[allow(clippy::too_many_arguments)]
333 pub fn draw_indexed_patches(
334 &self,
335 number_of_patch_control_points: UInteger,
336 patch_start: UInteger,
337 patch_count: UInteger,
338 patch_index_buffer: Option<&Buffer>,
339 patch_index_buffer_offset: UInteger,
340 control_point_index_buffer: &Buffer,
341 control_point_index_buffer_offset: UInteger,
342 instance_count: UInteger,
343 base_instance: UInteger,
344 ) {
345 let patch_index_buffer_ptr = patch_index_buffer
346 .map(|b| b.as_ptr())
347 .unwrap_or(std::ptr::null());
348 unsafe {
349 mtl_sys::msg_send_9::<
350 (),
351 UInteger,
352 UInteger,
353 UInteger,
354 *const c_void,
355 UInteger,
356 *const c_void,
357 UInteger,
358 UInteger,
359 UInteger,
360 >(
361 self.as_ptr(),
362 sel!(drawIndexedPatches: patchStart: patchCount: patchIndexBuffer: patchIndexBufferOffset: controlPointIndexBuffer: controlPointIndexBufferOffset: instanceCount: baseInstance:),
363 number_of_patch_control_points,
364 patch_start,
365 patch_count,
366 patch_index_buffer_ptr,
367 patch_index_buffer_offset,
368 control_point_index_buffer.as_ptr(),
369 control_point_index_buffer_offset,
370 instance_count,
371 base_instance,
372 );
373 }
374 }
375
376 #[allow(clippy::too_many_arguments)]
380 pub fn draw_indexed_patches_indirect(
381 &self,
382 number_of_patch_control_points: UInteger,
383 patch_index_buffer: Option<&Buffer>,
384 patch_index_buffer_offset: UInteger,
385 control_point_index_buffer: &Buffer,
386 control_point_index_buffer_offset: UInteger,
387 indirect_buffer: &Buffer,
388 indirect_buffer_offset: UInteger,
389 ) {
390 let patch_index_buffer_ptr = patch_index_buffer
391 .map(|b| b.as_ptr())
392 .unwrap_or(std::ptr::null());
393 unsafe {
394 mtl_sys::msg_send_7::<
395 (),
396 UInteger,
397 *const c_void,
398 UInteger,
399 *const c_void,
400 UInteger,
401 *const c_void,
402 UInteger,
403 >(
404 self.as_ptr(),
405 sel!(drawIndexedPatches: patchIndexBuffer: patchIndexBufferOffset: controlPointIndexBuffer: controlPointIndexBufferOffset: indirectBuffer: indirectBufferOffset:),
406 number_of_patch_control_points,
407 patch_index_buffer_ptr,
408 patch_index_buffer_offset,
409 control_point_index_buffer.as_ptr(),
410 control_point_index_buffer_offset,
411 indirect_buffer.as_ptr(),
412 indirect_buffer_offset,
413 );
414 }
415 }
416
417 pub fn draw_patches_indirect(
421 &self,
422 number_of_patch_control_points: UInteger,
423 patch_index_buffer: Option<&Buffer>,
424 patch_index_buffer_offset: UInteger,
425 indirect_buffer: &Buffer,
426 indirect_buffer_offset: UInteger,
427 ) {
428 let patch_index_buffer_ptr = patch_index_buffer
429 .map(|b| b.as_ptr())
430 .unwrap_or(std::ptr::null());
431 unsafe {
432 mtl_sys::msg_send_5::<(), UInteger, *const c_void, UInteger, *const c_void, UInteger>(
433 self.as_ptr(),
434 sel!(drawPatches: patchIndexBuffer: patchIndexBufferOffset: indirectBuffer: indirectBufferOffset:),
435 number_of_patch_control_points,
436 patch_index_buffer_ptr,
437 patch_index_buffer_offset,
438 indirect_buffer.as_ptr(),
439 indirect_buffer_offset,
440 );
441 }
442 }
443
444 #[inline]
452 pub fn draw_mesh_threadgroups(
453 &self,
454 threadgroups_per_grid: Size,
455 threads_per_object_threadgroup: Size,
456 threads_per_mesh_threadgroup: Size,
457 ) {
458 unsafe {
459 mtl_sys::msg_send_3::<(), Size, Size, Size>(
460 self.as_ptr(),
461 sel!(drawMeshThreadgroups: threadsPerObjectThreadgroup: threadsPerMeshThreadgroup:),
462 threadgroups_per_grid,
463 threads_per_object_threadgroup,
464 threads_per_mesh_threadgroup,
465 );
466 }
467 }
468
469 #[inline]
473 pub fn draw_mesh_threads(
474 &self,
475 threads_per_grid: Size,
476 threads_per_object_threadgroup: Size,
477 threads_per_mesh_threadgroup: Size,
478 ) {
479 unsafe {
480 mtl_sys::msg_send_3::<(), Size, Size, Size>(
481 self.as_ptr(),
482 sel!(drawMeshThreads: threadsPerObjectThreadgroup: threadsPerMeshThreadgroup:),
483 threads_per_grid,
484 threads_per_object_threadgroup,
485 threads_per_mesh_threadgroup,
486 );
487 }
488 }
489
490 #[inline]
494 pub fn draw_mesh_threadgroups_indirect(
495 &self,
496 indirect_buffer: &Buffer,
497 indirect_buffer_offset: UInteger,
498 threads_per_object_threadgroup: Size,
499 threads_per_mesh_threadgroup: Size,
500 ) {
501 unsafe {
502 mtl_sys::msg_send_4::<(), *const c_void, UInteger, Size, Size>(
503 self.as_ptr(),
504 sel!(drawMeshThreadgroupsWithIndirectBuffer: indirectBufferOffset: threadsPerObjectThreadgroup: threadsPerMeshThreadgroup:),
505 indirect_buffer.as_ptr(),
506 indirect_buffer_offset,
507 threads_per_object_threadgroup,
508 threads_per_mesh_threadgroup,
509 );
510 }
511 }
512
513 #[inline]
521 pub fn dispatch_threads_per_tile(&self, threads_per_tile: Size) {
522 unsafe {
523 msg_send_1::<(), Size>(
524 self.as_ptr(),
525 sel!(dispatchThreadsPerTile:),
526 threads_per_tile,
527 );
528 }
529 }
530}