1use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::{msg_send_0, msg_send_1, sel};
10
11use crate::enums::{PixelFormat, ShaderValidation};
12use crate::types::Size;
13
14use super::PipelineBufferDescriptorArray;
15
16pub struct TileRenderPipelineColorAttachmentDescriptor(pub(crate) NonNull<c_void>);
17
18impl TileRenderPipelineColorAttachmentDescriptor {
19 pub fn alloc() -> Option<Self> {
23 unsafe {
24 let cls = mtl_sys::Class::get("MTLTileRenderPipelineColorAttachmentDescriptor")?;
25 let ptr: *mut c_void = msg_send_0(cls.as_ptr(), sel!(alloc));
26 Self::from_raw(ptr)
27 }
28 }
29
30 pub fn init(&self) -> Option<Self> {
34 unsafe {
35 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(init));
36 Self::from_raw(ptr)
37 }
38 }
39
40 pub fn new() -> Option<Self> {
42 Self::alloc()?.init()
43 }
44
45 #[inline]
51 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
52 NonNull::new(ptr).map(Self)
53 }
54
55 #[inline]
57 pub fn as_raw(&self) -> *mut c_void {
58 self.0.as_ptr()
59 }
60
61 #[inline]
65 pub fn pixel_format(&self) -> PixelFormat {
66 unsafe { msg_send_0(self.as_ptr(), sel!(pixelFormat)) }
67 }
68
69 #[inline]
73 pub fn set_pixel_format(&self, format: PixelFormat) {
74 unsafe {
75 msg_send_1::<(), PixelFormat>(self.as_ptr(), sel!(setPixelFormat:), format);
76 }
77 }
78}
79
80impl Default for TileRenderPipelineColorAttachmentDescriptor {
81 fn default() -> Self {
82 Self::new().expect("failed to create TileRenderPipelineColorAttachmentDescriptor")
83 }
84}
85
86impl Clone for TileRenderPipelineColorAttachmentDescriptor {
87 fn clone(&self) -> Self {
88 unsafe {
89 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
90 Self::from_raw(ptr).expect("copy returned null")
91 }
92 }
93}
94
95impl Drop for TileRenderPipelineColorAttachmentDescriptor {
96 fn drop(&mut self) {
97 unsafe {
98 msg_send_0::<()>(self.as_ptr(), sel!(release));
99 }
100 }
101}
102
103impl Referencing for TileRenderPipelineColorAttachmentDescriptor {
104 #[inline]
105 fn as_ptr(&self) -> *const c_void {
106 self.0.as_ptr()
107 }
108}
109
110unsafe impl Send for TileRenderPipelineColorAttachmentDescriptor {}
111unsafe impl Sync for TileRenderPipelineColorAttachmentDescriptor {}
112
113impl std::fmt::Debug for TileRenderPipelineColorAttachmentDescriptor {
114 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115 f.debug_struct("TileRenderPipelineColorAttachmentDescriptor")
116 .field("pixel_format", &self.pixel_format())
117 .finish()
118 }
119}
120
121#[repr(transparent)]
129pub struct TileRenderPipelineColorAttachmentDescriptorArray(pub(crate) NonNull<c_void>);
130
131impl TileRenderPipelineColorAttachmentDescriptorArray {
132 #[inline]
138 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
139 NonNull::new(ptr).map(Self)
140 }
141
142 #[inline]
144 pub fn as_raw(&self) -> *mut c_void {
145 self.0.as_ptr()
146 }
147
148 pub fn object(&self, index: UInteger) -> Option<TileRenderPipelineColorAttachmentDescriptor> {
152 unsafe {
153 let ptr: *mut c_void =
154 msg_send_1(self.as_ptr(), sel!(objectAtIndexedSubscript:), index);
155 if ptr.is_null() {
156 return None;
157 }
158 msg_send_0::<*mut c_void>(ptr as *const c_void, sel!(retain));
159 TileRenderPipelineColorAttachmentDescriptor::from_raw(ptr)
160 }
161 }
162
163 pub fn set_object(
167 &self,
168 descriptor: Option<&TileRenderPipelineColorAttachmentDescriptor>,
169 index: UInteger,
170 ) {
171 let ptr = descriptor.map(|d| d.as_ptr()).unwrap_or(std::ptr::null());
172 unsafe {
173 let _: () = mtl_sys::msg_send_2(
174 self.as_ptr(),
175 sel!(setObject: atIndexedSubscript:),
176 ptr,
177 index,
178 );
179 }
180 }
181}
182
183impl Clone for TileRenderPipelineColorAttachmentDescriptorArray {
184 fn clone(&self) -> Self {
185 unsafe {
186 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
187 }
188 Self(self.0)
189 }
190}
191
192impl Drop for TileRenderPipelineColorAttachmentDescriptorArray {
193 fn drop(&mut self) {
194 unsafe {
195 msg_send_0::<()>(self.as_ptr(), sel!(release));
196 }
197 }
198}
199
200impl Referencing for TileRenderPipelineColorAttachmentDescriptorArray {
201 #[inline]
202 fn as_ptr(&self) -> *const c_void {
203 self.0.as_ptr()
204 }
205}
206
207unsafe impl Send for TileRenderPipelineColorAttachmentDescriptorArray {}
208unsafe impl Sync for TileRenderPipelineColorAttachmentDescriptorArray {}
209
210impl std::fmt::Debug for TileRenderPipelineColorAttachmentDescriptorArray {
211 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
212 f.debug_struct("TileRenderPipelineColorAttachmentDescriptorArray")
213 .finish()
214 }
215}
216
217#[repr(transparent)]
225pub struct TileRenderPipelineDescriptor(pub(crate) NonNull<c_void>);
226
227impl TileRenderPipelineDescriptor {
228 pub fn alloc() -> Option<Self> {
232 unsafe {
233 let cls = mtl_sys::Class::get("MTLTileRenderPipelineDescriptor")?;
234 let ptr: *mut c_void = msg_send_0(cls.as_ptr(), sel!(alloc));
235 Self::from_raw(ptr)
236 }
237 }
238
239 pub fn init(&self) -> Option<Self> {
243 unsafe {
244 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(init));
245 Self::from_raw(ptr)
246 }
247 }
248
249 pub fn new() -> Option<Self> {
251 Self::alloc()?.init()
252 }
253
254 #[inline]
260 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
261 NonNull::new(ptr).map(Self)
262 }
263
264 #[inline]
266 pub fn as_raw(&self) -> *mut c_void {
267 self.0.as_ptr()
268 }
269
270 pub fn label(&self) -> Option<String> {
278 unsafe {
279 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
280 if ptr.is_null() {
281 return None;
282 }
283 let utf8_ptr: *const std::ffi::c_char =
284 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
285 if utf8_ptr.is_null() {
286 return None;
287 }
288 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
289 Some(c_str.to_string_lossy().into_owned())
290 }
291 }
292
293 pub fn set_label(&self, label: &str) {
297 if let Some(ns_label) = mtl_foundation::String::from_str(label) {
298 unsafe {
299 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
300 }
301 }
302 }
303
304 pub fn tile_function(&self) -> Option<crate::Function> {
308 unsafe {
309 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(tileFunction));
310 if ptr.is_null() {
311 return None;
312 }
313 msg_send_0::<*mut c_void>(ptr as *const c_void, sel!(retain));
314 crate::Function::from_raw(ptr)
315 }
316 }
317
318 pub fn set_tile_function(&self, function: Option<&crate::Function>) {
322 let ptr = function.map(|f| f.as_ptr()).unwrap_or(std::ptr::null());
323 unsafe {
324 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setTileFunction:), ptr);
325 }
326 }
327
328 #[inline]
332 pub fn raster_sample_count(&self) -> UInteger {
333 unsafe { msg_send_0(self.as_ptr(), sel!(rasterSampleCount)) }
334 }
335
336 #[inline]
340 pub fn set_raster_sample_count(&self, count: UInteger) {
341 unsafe {
342 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setRasterSampleCount:), count);
343 }
344 }
345
346 pub fn color_attachments(&self) -> Option<TileRenderPipelineColorAttachmentDescriptorArray> {
350 unsafe {
351 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(colorAttachments));
352 TileRenderPipelineColorAttachmentDescriptorArray::from_raw(ptr)
353 }
354 }
355
356 #[inline]
360 pub fn threadgroup_size_matches_tile_size(&self) -> bool {
361 unsafe { msg_send_0(self.as_ptr(), sel!(threadgroupSizeMatchesTileSize)) }
362 }
363
364 #[inline]
368 pub fn set_threadgroup_size_matches_tile_size(&self, matches: bool) {
369 unsafe {
370 msg_send_1::<(), bool>(
371 self.as_ptr(),
372 sel!(setThreadgroupSizeMatchesTileSize:),
373 matches,
374 );
375 }
376 }
377
378 pub fn tile_buffers(&self) -> Option<PipelineBufferDescriptorArray> {
382 unsafe {
383 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(tileBuffers));
384 PipelineBufferDescriptorArray::from_raw(ptr)
385 }
386 }
387
388 #[inline]
392 pub fn max_total_threads_per_threadgroup(&self) -> UInteger {
393 unsafe { msg_send_0(self.as_ptr(), sel!(maxTotalThreadsPerThreadgroup)) }
394 }
395
396 #[inline]
400 pub fn set_max_total_threads_per_threadgroup(&self, count: UInteger) {
401 unsafe {
402 msg_send_1::<(), UInteger>(
403 self.as_ptr(),
404 sel!(setMaxTotalThreadsPerThreadgroup:),
405 count,
406 );
407 }
408 }
409
410 #[inline]
414 pub fn required_threads_per_threadgroup(&self) -> Size {
415 unsafe { msg_send_0(self.as_ptr(), sel!(requiredThreadsPerThreadgroup)) }
416 }
417
418 #[inline]
422 pub fn set_required_threads_per_threadgroup(&self, size: Size) {
423 unsafe {
424 msg_send_1::<(), Size>(self.as_ptr(), sel!(setRequiredThreadsPerThreadgroup:), size);
425 }
426 }
427
428 #[inline]
432 pub fn max_call_stack_depth(&self) -> UInteger {
433 unsafe { msg_send_0(self.as_ptr(), sel!(maxCallStackDepth)) }
434 }
435
436 #[inline]
440 pub fn set_max_call_stack_depth(&self, depth: UInteger) {
441 unsafe {
442 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setMaxCallStackDepth:), depth);
443 }
444 }
445
446 pub fn linked_functions(&self) -> Option<crate::LinkedFunctions> {
450 unsafe {
451 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(linkedFunctions));
452 if ptr.is_null() {
453 return None;
454 }
455 msg_send_0::<*mut c_void>(ptr as *const c_void, sel!(retain));
456 crate::LinkedFunctions::from_raw(ptr)
457 }
458 }
459
460 pub fn set_linked_functions(&self, functions: Option<&crate::LinkedFunctions>) {
464 let ptr = functions.map(|f| f.as_ptr()).unwrap_or(std::ptr::null());
465 unsafe {
466 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setLinkedFunctions:), ptr);
467 }
468 }
469
470 #[inline]
474 pub fn support_adding_binary_functions(&self) -> bool {
475 unsafe { msg_send_0(self.as_ptr(), sel!(supportAddingBinaryFunctions)) }
476 }
477
478 #[inline]
482 pub fn set_support_adding_binary_functions(&self, support: bool) {
483 unsafe {
484 msg_send_1::<(), bool>(
485 self.as_ptr(),
486 sel!(setSupportAddingBinaryFunctions:),
487 support,
488 );
489 }
490 }
491
492 #[inline]
496 pub fn shader_validation(&self) -> ShaderValidation {
497 unsafe { msg_send_0(self.as_ptr(), sel!(shaderValidation)) }
498 }
499
500 #[inline]
504 pub fn set_shader_validation(&self, validation: ShaderValidation) {
505 unsafe {
506 msg_send_1::<(), ShaderValidation>(
507 self.as_ptr(),
508 sel!(setShaderValidation:),
509 validation,
510 );
511 }
512 }
513
514 pub fn binary_archives_raw(&self) -> *mut c_void {
518 unsafe { msg_send_0(self.as_ptr(), sel!(binaryArchives)) }
519 }
520
521 pub unsafe fn set_binary_archives_raw(&self, archives: *const c_void) {
529 unsafe {
530 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setBinaryArchives:), archives);
531 }
532 }
533
534 pub fn preloaded_libraries_raw(&self) -> *mut c_void {
538 unsafe { msg_send_0(self.as_ptr(), sel!(preloadedLibraries)) }
539 }
540
541 pub unsafe fn set_preloaded_libraries_raw(&self, libraries: *const c_void) {
549 unsafe {
550 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setPreloadedLibraries:), libraries);
551 }
552 }
553
554 #[inline]
558 pub fn reset(&self) {
559 unsafe {
560 msg_send_0::<()>(self.as_ptr(), sel!(reset));
561 }
562 }
563}
564
565impl Default for TileRenderPipelineDescriptor {
566 fn default() -> Self {
567 Self::new().expect("failed to create TileRenderPipelineDescriptor")
568 }
569}
570
571impl Clone for TileRenderPipelineDescriptor {
572 fn clone(&self) -> Self {
573 unsafe {
574 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
575 Self::from_raw(ptr).expect("copy returned null")
576 }
577 }
578}
579
580impl Drop for TileRenderPipelineDescriptor {
581 fn drop(&mut self) {
582 unsafe {
583 msg_send_0::<()>(self.as_ptr(), sel!(release));
584 }
585 }
586}
587
588impl Referencing for TileRenderPipelineDescriptor {
589 #[inline]
590 fn as_ptr(&self) -> *const c_void {
591 self.0.as_ptr()
592 }
593}
594
595unsafe impl Send for TileRenderPipelineDescriptor {}
596unsafe impl Sync for TileRenderPipelineDescriptor {}
597
598impl std::fmt::Debug for TileRenderPipelineDescriptor {
599 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
600 f.debug_struct("TileRenderPipelineDescriptor")
601 .field("label", &self.label())
602 .field("raster_sample_count", &self.raster_sample_count())
603 .finish()
604 }
605}