mtl_gpu/rasterization_rate/
mod.rs1use std::ffi::c_void;
9use std::ptr::NonNull;
10
11use mtl_foundation::{Referencing, UInteger};
12use mtl_sys::{Class, msg_send_0, msg_send_1, msg_send_2, sel};
13
14use crate::Buffer;
15use crate::types::{Coordinate2D, Size, SizeAndAlign};
16
17#[repr(transparent)]
25pub struct RasterizationRateSampleArray(pub(crate) NonNull<c_void>);
26
27impl RasterizationRateSampleArray {
28 pub fn new() -> Option<Self> {
32 unsafe {
33 let class = Class::get("MTLRasterizationRateSampleArray")?;
34 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
35 if ptr.is_null() {
36 return None;
37 }
38 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
39 Self::from_raw(ptr)
40 }
41 }
42
43 #[inline]
45 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
46 NonNull::new(ptr).map(Self)
47 }
48
49 #[inline]
51 pub fn as_raw(&self) -> *mut c_void {
52 self.0.as_ptr()
53 }
54
55 pub fn object_raw(&self, index: UInteger) -> *mut c_void {
59 unsafe { msg_send_1(self.as_ptr(), sel!(objectAtIndexedSubscript:), index) }
60 }
61
62 pub fn set_object_raw(&self, value: *const c_void, index: UInteger) {
66 unsafe {
67 let _: () = msg_send_2(
68 self.as_ptr(),
69 sel!(setObject:atIndexedSubscript:),
70 value,
71 index,
72 );
73 }
74 }
75}
76
77impl Clone for RasterizationRateSampleArray {
78 fn clone(&self) -> Self {
79 unsafe {
80 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
81 }
82 Self(self.0)
83 }
84}
85
86impl Drop for RasterizationRateSampleArray {
87 fn drop(&mut self) {
88 unsafe {
89 msg_send_0::<()>(self.as_ptr(), sel!(release));
90 }
91 }
92}
93
94impl Referencing for RasterizationRateSampleArray {
95 #[inline]
96 fn as_ptr(&self) -> *const c_void {
97 self.0.as_ptr()
98 }
99}
100
101unsafe impl Send for RasterizationRateSampleArray {}
102unsafe impl Sync for RasterizationRateSampleArray {}
103
104impl std::fmt::Debug for RasterizationRateSampleArray {
105 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106 f.debug_struct("RasterizationRateSampleArray").finish()
107 }
108}
109
110#[repr(transparent)]
118pub struct RasterizationRateLayerDescriptor(pub(crate) NonNull<c_void>);
119
120impl RasterizationRateLayerDescriptor {
121 pub fn new() -> Option<Self> {
125 unsafe {
126 let class = Class::get("MTLRasterizationRateLayerDescriptor")?;
127 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
128 if ptr.is_null() {
129 return None;
130 }
131 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
132 Self::from_raw(ptr)
133 }
134 }
135
136 pub fn with_sample_count(sample_count: Size) -> Option<Self> {
140 unsafe {
141 let class = Class::get("MTLRasterizationRateLayerDescriptor")?;
142 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
143 if ptr.is_null() {
144 return None;
145 }
146 let ptr: *mut c_void = msg_send_1(ptr, sel!(initWithSampleCount:), sample_count);
147 Self::from_raw(ptr)
148 }
149 }
150
151 pub fn with_sample_count_and_data(
155 sample_count: Size,
156 horizontal: *const f32,
157 vertical: *const f32,
158 ) -> Option<Self> {
159 unsafe {
160 let class = Class::get("MTLRasterizationRateLayerDescriptor")?;
161 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
162 if ptr.is_null() {
163 return None;
164 }
165 let ptr: *mut c_void = mtl_sys::msg_send_3(
166 ptr,
167 sel!(initWithSampleCount:horizontal:vertical:),
168 sample_count,
169 horizontal,
170 vertical,
171 );
172 Self::from_raw(ptr)
173 }
174 }
175
176 #[inline]
178 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
179 NonNull::new(ptr).map(Self)
180 }
181
182 #[inline]
184 pub fn as_raw(&self) -> *mut c_void {
185 self.0.as_ptr()
186 }
187
188 #[inline]
196 pub fn sample_count(&self) -> Size {
197 unsafe { msg_send_0(self.as_ptr(), sel!(sampleCount)) }
198 }
199
200 #[inline]
204 pub fn set_sample_count(&self, sample_count: Size) {
205 unsafe {
206 let _: () = msg_send_1(self.as_ptr(), sel!(setSampleCount:), sample_count);
207 }
208 }
209
210 #[inline]
214 pub fn max_sample_count(&self) -> Size {
215 unsafe { msg_send_0(self.as_ptr(), sel!(maxSampleCount)) }
216 }
217
218 pub fn horizontal(&self) -> RasterizationRateSampleArray {
222 unsafe {
223 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(horizontal));
224 msg_send_0::<*mut c_void>(ptr, sel!(retain));
225 RasterizationRateSampleArray::from_raw(ptr)
226 .expect("horizontal sample array should not be null")
227 }
228 }
229
230 pub fn vertical(&self) -> RasterizationRateSampleArray {
234 unsafe {
235 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(vertical));
236 msg_send_0::<*mut c_void>(ptr, sel!(retain));
237 RasterizationRateSampleArray::from_raw(ptr)
238 .expect("vertical sample array should not be null")
239 }
240 }
241
242 #[inline]
246 pub fn horizontal_sample_storage(&self) -> *mut f32 {
247 unsafe { msg_send_0(self.as_ptr(), sel!(horizontalSampleStorage)) }
248 }
249
250 #[inline]
254 pub fn vertical_sample_storage(&self) -> *mut f32 {
255 unsafe { msg_send_0(self.as_ptr(), sel!(verticalSampleStorage)) }
256 }
257}
258
259impl Clone for RasterizationRateLayerDescriptor {
260 fn clone(&self) -> Self {
261 unsafe {
262 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
263 }
264 Self(self.0)
265 }
266}
267
268impl Drop for RasterizationRateLayerDescriptor {
269 fn drop(&mut self) {
270 unsafe {
271 msg_send_0::<()>(self.as_ptr(), sel!(release));
272 }
273 }
274}
275
276impl Referencing for RasterizationRateLayerDescriptor {
277 #[inline]
278 fn as_ptr(&self) -> *const c_void {
279 self.0.as_ptr()
280 }
281}
282
283unsafe impl Send for RasterizationRateLayerDescriptor {}
284unsafe impl Sync for RasterizationRateLayerDescriptor {}
285
286impl std::fmt::Debug for RasterizationRateLayerDescriptor {
287 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
288 f.debug_struct("RasterizationRateLayerDescriptor")
289 .field("sample_count", &self.sample_count())
290 .finish()
291 }
292}
293
294#[repr(transparent)]
302pub struct RasterizationRateLayerArray(pub(crate) NonNull<c_void>);
303
304impl RasterizationRateLayerArray {
305 pub fn new() -> Option<Self> {
309 unsafe {
310 let class = Class::get("MTLRasterizationRateLayerArray")?;
311 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
312 if ptr.is_null() {
313 return None;
314 }
315 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
316 Self::from_raw(ptr)
317 }
318 }
319
320 #[inline]
322 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
323 NonNull::new(ptr).map(Self)
324 }
325
326 #[inline]
328 pub fn as_raw(&self) -> *mut c_void {
329 self.0.as_ptr()
330 }
331
332 pub fn object(&self, layer_index: UInteger) -> Option<RasterizationRateLayerDescriptor> {
336 unsafe {
337 let ptr: *mut c_void =
338 msg_send_1(self.as_ptr(), sel!(objectAtIndexedSubscript:), layer_index);
339 if ptr.is_null() {
340 return None;
341 }
342 msg_send_0::<*mut c_void>(ptr, sel!(retain));
343 RasterizationRateLayerDescriptor::from_raw(ptr)
344 }
345 }
346
347 pub fn set_object(&self, layer: &RasterizationRateLayerDescriptor, layer_index: UInteger) {
351 unsafe {
352 let _: () = msg_send_2(
353 self.as_ptr(),
354 sel!(setObject:atIndexedSubscript:),
355 layer.as_ptr(),
356 layer_index,
357 );
358 }
359 }
360}
361
362impl Clone for RasterizationRateLayerArray {
363 fn clone(&self) -> Self {
364 unsafe {
365 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
366 }
367 Self(self.0)
368 }
369}
370
371impl Drop for RasterizationRateLayerArray {
372 fn drop(&mut self) {
373 unsafe {
374 msg_send_0::<()>(self.as_ptr(), sel!(release));
375 }
376 }
377}
378
379impl Referencing for RasterizationRateLayerArray {
380 #[inline]
381 fn as_ptr(&self) -> *const c_void {
382 self.0.as_ptr()
383 }
384}
385
386unsafe impl Send for RasterizationRateLayerArray {}
387unsafe impl Sync for RasterizationRateLayerArray {}
388
389impl std::fmt::Debug for RasterizationRateLayerArray {
390 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
391 f.debug_struct("RasterizationRateLayerArray").finish()
392 }
393}
394
395#[repr(transparent)]
403pub struct RasterizationRateMapDescriptor(pub(crate) NonNull<c_void>);
404
405impl RasterizationRateMapDescriptor {
406 pub fn new() -> Option<Self> {
410 unsafe {
411 let class = Class::get("MTLRasterizationRateMapDescriptor")?;
412 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
413 if ptr.is_null() {
414 return None;
415 }
416 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
417 Self::from_raw(ptr)
418 }
419 }
420
421 pub fn with_screen_size(screen_size: Size) -> Option<Self> {
425 unsafe {
426 let class = Class::get("MTLRasterizationRateMapDescriptor")?;
427 let ptr: *mut c_void = msg_send_1(
428 class.as_ptr(),
429 sel!(rasterizationRateMapDescriptorWithScreenSize:),
430 screen_size,
431 );
432 if ptr.is_null() {
433 return None;
434 }
435 msg_send_0::<*mut c_void>(ptr, sel!(retain));
436 Self::from_raw(ptr)
437 }
438 }
439
440 pub fn with_screen_size_and_layer(
444 screen_size: Size,
445 layer: &RasterizationRateLayerDescriptor,
446 ) -> Option<Self> {
447 unsafe {
448 let class = Class::get("MTLRasterizationRateMapDescriptor")?;
449 let ptr: *mut c_void = msg_send_2(
450 class.as_ptr(),
451 sel!(rasterizationRateMapDescriptorWithScreenSize:layer:),
452 screen_size,
453 layer.as_ptr(),
454 );
455 if ptr.is_null() {
456 return None;
457 }
458 msg_send_0::<*mut c_void>(ptr, sel!(retain));
459 Self::from_raw(ptr)
460 }
461 }
462
463 #[inline]
465 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
466 NonNull::new(ptr).map(Self)
467 }
468
469 #[inline]
471 pub fn as_raw(&self) -> *mut c_void {
472 self.0.as_ptr()
473 }
474
475 pub fn label(&self) -> Option<String> {
483 unsafe {
484 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
485 if ptr.is_null() {
486 return None;
487 }
488 let utf8_ptr: *const std::ffi::c_char =
489 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
490 if utf8_ptr.is_null() {
491 return None;
492 }
493 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
494 Some(c_str.to_string_lossy().into_owned())
495 }
496 }
497
498 pub fn set_label(&self, label: &str) {
502 if let Some(ns_label) = mtl_foundation::String::from_str(label) {
503 unsafe {
504 let _: () = msg_send_1(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
505 }
506 }
507 }
508
509 #[inline]
513 pub fn screen_size(&self) -> Size {
514 unsafe { msg_send_0(self.as_ptr(), sel!(screenSize)) }
515 }
516
517 #[inline]
521 pub fn set_screen_size(&self, screen_size: Size) {
522 unsafe {
523 let _: () = msg_send_1(self.as_ptr(), sel!(setScreenSize:), screen_size);
524 }
525 }
526
527 #[inline]
531 pub fn layer_count(&self) -> UInteger {
532 unsafe { msg_send_0(self.as_ptr(), sel!(layerCount)) }
533 }
534
535 pub fn layers(&self) -> RasterizationRateLayerArray {
539 unsafe {
540 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(layers));
541 msg_send_0::<*mut c_void>(ptr, sel!(retain));
542 RasterizationRateLayerArray::from_raw(ptr).expect("layers should not be null")
543 }
544 }
545
546 pub fn layer(&self, layer_index: UInteger) -> Option<RasterizationRateLayerDescriptor> {
550 unsafe {
551 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(layerAtIndex:), layer_index);
552 if ptr.is_null() {
553 return None;
554 }
555 msg_send_0::<*mut c_void>(ptr, sel!(retain));
556 RasterizationRateLayerDescriptor::from_raw(ptr)
557 }
558 }
559
560 pub fn set_layer(&self, layer: &RasterizationRateLayerDescriptor, layer_index: UInteger) {
564 unsafe {
565 let _: () = msg_send_2(
566 self.as_ptr(),
567 sel!(setLayer:atIndex:),
568 layer.as_ptr(),
569 layer_index,
570 );
571 }
572 }
573}
574
575impl Clone for RasterizationRateMapDescriptor {
576 fn clone(&self) -> Self {
577 unsafe {
578 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
579 }
580 Self(self.0)
581 }
582}
583
584impl Drop for RasterizationRateMapDescriptor {
585 fn drop(&mut self) {
586 unsafe {
587 msg_send_0::<()>(self.as_ptr(), sel!(release));
588 }
589 }
590}
591
592impl Referencing for RasterizationRateMapDescriptor {
593 #[inline]
594 fn as_ptr(&self) -> *const c_void {
595 self.0.as_ptr()
596 }
597}
598
599unsafe impl Send for RasterizationRateMapDescriptor {}
600unsafe impl Sync for RasterizationRateMapDescriptor {}
601
602impl std::fmt::Debug for RasterizationRateMapDescriptor {
603 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
604 f.debug_struct("RasterizationRateMapDescriptor")
605 .field("label", &self.label())
606 .field("screen_size", &self.screen_size())
607 .field("layer_count", &self.layer_count())
608 .finish()
609 }
610}
611
612#[repr(transparent)]
620pub struct RasterizationRateMap(pub(crate) NonNull<c_void>);
621
622impl RasterizationRateMap {
623 #[inline]
625 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
626 NonNull::new(ptr).map(Self)
627 }
628
629 #[inline]
631 pub fn as_raw(&self) -> *mut c_void {
632 self.0.as_ptr()
633 }
634
635 pub fn device(&self) -> crate::Device {
643 unsafe {
644 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(device));
645 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
646 crate::Device::from_raw(ptr).expect("rasterization rate map has no device")
647 }
648 }
649
650 pub fn label(&self) -> Option<String> {
654 unsafe {
655 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
656 if ptr.is_null() {
657 return None;
658 }
659 let utf8_ptr: *const std::ffi::c_char =
660 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
661 if utf8_ptr.is_null() {
662 return None;
663 }
664 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
665 Some(c_str.to_string_lossy().into_owned())
666 }
667 }
668
669 #[inline]
673 pub fn screen_size(&self) -> Size {
674 unsafe { msg_send_0(self.as_ptr(), sel!(screenSize)) }
675 }
676
677 #[inline]
681 pub fn physical_granularity(&self) -> Size {
682 unsafe { msg_send_0(self.as_ptr(), sel!(physicalGranularity)) }
683 }
684
685 #[inline]
689 pub fn layer_count(&self) -> UInteger {
690 unsafe { msg_send_0(self.as_ptr(), sel!(layerCount)) }
691 }
692
693 #[inline]
697 pub fn parameter_buffer_size_and_align(&self) -> SizeAndAlign {
698 unsafe { msg_send_0(self.as_ptr(), sel!(parameterBufferSizeAndAlign)) }
699 }
700
701 #[inline]
709 pub fn physical_size(&self, layer_index: UInteger) -> Size {
710 unsafe { msg_send_1(self.as_ptr(), sel!(physicalSizeForLayer:), layer_index) }
711 }
712
713 #[inline]
717 pub fn map_physical_to_screen_coordinates(
718 &self,
719 physical_coordinates: Coordinate2D,
720 layer_index: UInteger,
721 ) -> Coordinate2D {
722 unsafe {
723 msg_send_2(
724 self.as_ptr(),
725 sel!(mapPhysicalToScreenCoordinates:forLayer:),
726 physical_coordinates,
727 layer_index,
728 )
729 }
730 }
731
732 #[inline]
736 pub fn map_screen_to_physical_coordinates(
737 &self,
738 screen_coordinates: Coordinate2D,
739 layer_index: UInteger,
740 ) -> Coordinate2D {
741 unsafe {
742 msg_send_2(
743 self.as_ptr(),
744 sel!(mapScreenToPhysicalCoordinates:forLayer:),
745 screen_coordinates,
746 layer_index,
747 )
748 }
749 }
750
751 pub fn copy_parameter_data_to_buffer(&self, buffer: &Buffer, offset: UInteger) {
755 unsafe {
756 let _: () = msg_send_2(
757 self.as_ptr(),
758 sel!(copyParameterDataToBuffer:offset:),
759 buffer.as_ptr(),
760 offset,
761 );
762 }
763 }
764}
765
766impl Clone for RasterizationRateMap {
767 fn clone(&self) -> Self {
768 unsafe {
769 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
770 }
771 Self(self.0)
772 }
773}
774
775impl Drop for RasterizationRateMap {
776 fn drop(&mut self) {
777 unsafe {
778 msg_send_0::<()>(self.as_ptr(), sel!(release));
779 }
780 }
781}
782
783impl Referencing for RasterizationRateMap {
784 #[inline]
785 fn as_ptr(&self) -> *const c_void {
786 self.0.as_ptr()
787 }
788}
789
790unsafe impl Send for RasterizationRateMap {}
791unsafe impl Sync for RasterizationRateMap {}
792
793impl std::fmt::Debug for RasterizationRateMap {
794 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
795 f.debug_struct("RasterizationRateMap")
796 .field("label", &self.label())
797 .field("screen_size", &self.screen_size())
798 .field("layer_count", &self.layer_count())
799 .finish()
800 }
801}
802
803#[cfg(test)]
808mod tests {
809 use super::*;
810
811 #[test]
812 fn test_rasterization_rate_map_descriptor_size() {
813 assert_eq!(
814 std::mem::size_of::<RasterizationRateMapDescriptor>(),
815 std::mem::size_of::<*mut c_void>()
816 );
817 }
818
819 #[test]
820 fn test_rasterization_rate_map_size() {
821 assert_eq!(
822 std::mem::size_of::<RasterizationRateMap>(),
823 std::mem::size_of::<*mut c_void>()
824 );
825 }
826
827 #[test]
828 fn test_rasterization_rate_layer_descriptor_size() {
829 assert_eq!(
830 std::mem::size_of::<RasterizationRateLayerDescriptor>(),
831 std::mem::size_of::<*mut c_void>()
832 );
833 }
834}