Skip to main content

mtl_gpu/rasterization_rate/
mod.rs

1//! Rasterization rate types for variable rate shading.
2//!
3//! Corresponds to `Metal/MTLRasterizationRate.hpp`.
4//!
5//! Rasterization rate maps allow you to vary the shading rate across the render target,
6//! enabling foveated rendering and other optimization techniques.
7
8use 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// ============================================================================
18// RasterizationRateSampleArray
19// ============================================================================
20
21/// An array of rasterization rate samples.
22///
23/// C++ equivalent: `MTL::RasterizationRateSampleArray`
24#[repr(transparent)]
25pub struct RasterizationRateSampleArray(pub(crate) NonNull<c_void>);
26
27impl RasterizationRateSampleArray {
28    /// Create a new rasterization rate sample array.
29    ///
30    /// C++ equivalent: `static RasterizationRateSampleArray* alloc()->init()`
31    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    /// Create from a raw pointer.
44    #[inline]
45    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
46        NonNull::new(ptr).map(Self)
47    }
48
49    /// Get the raw pointer.
50    #[inline]
51    pub fn as_raw(&self) -> *mut c_void {
52        self.0.as_ptr()
53    }
54
55    /// Get the sample value at the specified index as a raw NS::Number pointer.
56    ///
57    /// C++ equivalent: `NS::Number* object(NS::UInteger index)`
58    pub fn object_raw(&self, index: UInteger) -> *mut c_void {
59        unsafe { msg_send_1(self.as_ptr(), sel!(objectAtIndexedSubscript:), index) }
60    }
61
62    /// Set the sample value at the specified index.
63    ///
64    /// C++ equivalent: `void setObject(const NS::Number* value, NS::UInteger index)`
65    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// ============================================================================
111// RasterizationRateLayerDescriptor
112// ============================================================================
113
114/// A descriptor for a rasterization rate layer.
115///
116/// C++ equivalent: `MTL::RasterizationRateLayerDescriptor`
117#[repr(transparent)]
118pub struct RasterizationRateLayerDescriptor(pub(crate) NonNull<c_void>);
119
120impl RasterizationRateLayerDescriptor {
121    /// Create a new rasterization rate layer descriptor.
122    ///
123    /// C++ equivalent: `static RasterizationRateLayerDescriptor* alloc()->init()`
124    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    /// Create a new rasterization rate layer descriptor with the specified sample count.
137    ///
138    /// C++ equivalent: `RasterizationRateLayerDescriptor* init(MTL::Size sampleCount)`
139    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    /// Create a new rasterization rate layer descriptor with sample count and data.
152    ///
153    /// C++ equivalent: `RasterizationRateLayerDescriptor* init(MTL::Size sampleCount, const float* horizontal, const float* vertical)`
154    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    /// Create from a raw pointer.
177    #[inline]
178    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
179        NonNull::new(ptr).map(Self)
180    }
181
182    /// Get the raw pointer.
183    #[inline]
184    pub fn as_raw(&self) -> *mut c_void {
185        self.0.as_ptr()
186    }
187
188    // =========================================================================
189    // Properties
190    // =========================================================================
191
192    /// Get the sample count.
193    ///
194    /// C++ equivalent: `Size sampleCount() const`
195    #[inline]
196    pub fn sample_count(&self) -> Size {
197        unsafe { msg_send_0(self.as_ptr(), sel!(sampleCount)) }
198    }
199
200    /// Set the sample count.
201    ///
202    /// C++ equivalent: `void setSampleCount(MTL::Size sampleCount)`
203    #[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    /// Get the maximum sample count.
211    ///
212    /// C++ equivalent: `Size maxSampleCount() const`
213    #[inline]
214    pub fn max_sample_count(&self) -> Size {
215        unsafe { msg_send_0(self.as_ptr(), sel!(maxSampleCount)) }
216    }
217
218    /// Get the horizontal sample array.
219    ///
220    /// C++ equivalent: `RasterizationRateSampleArray* horizontal() const`
221    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    /// Get the vertical sample array.
231    ///
232    /// C++ equivalent: `RasterizationRateSampleArray* vertical() const`
233    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    /// Get direct access to the horizontal sample storage.
243    ///
244    /// C++ equivalent: `float* horizontalSampleStorage() const`
245    #[inline]
246    pub fn horizontal_sample_storage(&self) -> *mut f32 {
247        unsafe { msg_send_0(self.as_ptr(), sel!(horizontalSampleStorage)) }
248    }
249
250    /// Get direct access to the vertical sample storage.
251    ///
252    /// C++ equivalent: `float* verticalSampleStorage() const`
253    #[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// ============================================================================
295// RasterizationRateLayerArray
296// ============================================================================
297
298/// An array of rasterization rate layer descriptors.
299///
300/// C++ equivalent: `MTL::RasterizationRateLayerArray`
301#[repr(transparent)]
302pub struct RasterizationRateLayerArray(pub(crate) NonNull<c_void>);
303
304impl RasterizationRateLayerArray {
305    /// Create a new rasterization rate layer array.
306    ///
307    /// C++ equivalent: `static RasterizationRateLayerArray* alloc()->init()`
308    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    /// Create from a raw pointer.
321    #[inline]
322    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
323        NonNull::new(ptr).map(Self)
324    }
325
326    /// Get the raw pointer.
327    #[inline]
328    pub fn as_raw(&self) -> *mut c_void {
329        self.0.as_ptr()
330    }
331
332    /// Get the layer descriptor at the specified index.
333    ///
334    /// C++ equivalent: `RasterizationRateLayerDescriptor* object(NS::UInteger layerIndex)`
335    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    /// Set the layer descriptor at the specified index.
348    ///
349    /// C++ equivalent: `void setObject(const MTL::RasterizationRateLayerDescriptor* layer, NS::UInteger layerIndex)`
350    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// ============================================================================
396// RasterizationRateMapDescriptor
397// ============================================================================
398
399/// A descriptor for creating a rasterization rate map.
400///
401/// C++ equivalent: `MTL::RasterizationRateMapDescriptor`
402#[repr(transparent)]
403pub struct RasterizationRateMapDescriptor(pub(crate) NonNull<c_void>);
404
405impl RasterizationRateMapDescriptor {
406    /// Create a new rasterization rate map descriptor.
407    ///
408    /// C++ equivalent: `static RasterizationRateMapDescriptor* alloc()->init()`
409    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    /// Create a rasterization rate map descriptor with screen size.
422    ///
423    /// C++ equivalent: `static RasterizationRateMapDescriptor* rasterizationRateMapDescriptor(MTL::Size screenSize)`
424    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    /// Create a rasterization rate map descriptor with screen size and a single layer.
441    ///
442    /// C++ equivalent: `static RasterizationRateMapDescriptor* rasterizationRateMapDescriptor(MTL::Size screenSize, const MTL::RasterizationRateLayerDescriptor* layer)`
443    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    /// Create from a raw pointer.
464    #[inline]
465    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
466        NonNull::new(ptr).map(Self)
467    }
468
469    /// Get the raw pointer.
470    #[inline]
471    pub fn as_raw(&self) -> *mut c_void {
472        self.0.as_ptr()
473    }
474
475    // =========================================================================
476    // Properties
477    // =========================================================================
478
479    /// Get the label.
480    ///
481    /// C++ equivalent: `NS::String* label() const`
482    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    /// Set the label.
499    ///
500    /// C++ equivalent: `void setLabel(const NS::String* label)`
501    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    /// Get the screen size.
510    ///
511    /// C++ equivalent: `Size screenSize() const`
512    #[inline]
513    pub fn screen_size(&self) -> Size {
514        unsafe { msg_send_0(self.as_ptr(), sel!(screenSize)) }
515    }
516
517    /// Set the screen size.
518    ///
519    /// C++ equivalent: `void setScreenSize(MTL::Size screenSize)`
520    #[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    /// Get the layer count.
528    ///
529    /// C++ equivalent: `NS::UInteger layerCount() const`
530    #[inline]
531    pub fn layer_count(&self) -> UInteger {
532        unsafe { msg_send_0(self.as_ptr(), sel!(layerCount)) }
533    }
534
535    /// Get the layers array.
536    ///
537    /// C++ equivalent: `RasterizationRateLayerArray* layers() const`
538    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    /// Get a layer at the specified index.
547    ///
548    /// C++ equivalent: `RasterizationRateLayerDescriptor* layer(NS::UInteger layerIndex)`
549    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    /// Set a layer at the specified index.
561    ///
562    /// C++ equivalent: `void setLayer(const MTL::RasterizationRateLayerDescriptor* layer, NS::UInteger layerIndex)`
563    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// ============================================================================
613// RasterizationRateMap
614// ============================================================================
615
616/// A rasterization rate map for variable rate shading.
617///
618/// C++ equivalent: `MTL::RasterizationRateMap`
619#[repr(transparent)]
620pub struct RasterizationRateMap(pub(crate) NonNull<c_void>);
621
622impl RasterizationRateMap {
623    /// Create from a raw pointer.
624    #[inline]
625    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
626        NonNull::new(ptr).map(Self)
627    }
628
629    /// Get the raw pointer.
630    #[inline]
631    pub fn as_raw(&self) -> *mut c_void {
632        self.0.as_ptr()
633    }
634
635    // =========================================================================
636    // Properties
637    // =========================================================================
638
639    /// Get the device that created this rasterization rate map.
640    ///
641    /// C++ equivalent: `Device* device() const`
642    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    /// Get the label.
651    ///
652    /// C++ equivalent: `NS::String* label() const`
653    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    /// Get the screen size.
670    ///
671    /// C++ equivalent: `Size screenSize() const`
672    #[inline]
673    pub fn screen_size(&self) -> Size {
674        unsafe { msg_send_0(self.as_ptr(), sel!(screenSize)) }
675    }
676
677    /// Get the physical granularity.
678    ///
679    /// C++ equivalent: `Size physicalGranularity() const`
680    #[inline]
681    pub fn physical_granularity(&self) -> Size {
682        unsafe { msg_send_0(self.as_ptr(), sel!(physicalGranularity)) }
683    }
684
685    /// Get the layer count.
686    ///
687    /// C++ equivalent: `NS::UInteger layerCount() const`
688    #[inline]
689    pub fn layer_count(&self) -> UInteger {
690        unsafe { msg_send_0(self.as_ptr(), sel!(layerCount)) }
691    }
692
693    /// Get the parameter buffer size and alignment.
694    ///
695    /// C++ equivalent: `SizeAndAlign parameterBufferSizeAndAlign() const`
696    #[inline]
697    pub fn parameter_buffer_size_and_align(&self) -> SizeAndAlign {
698        unsafe { msg_send_0(self.as_ptr(), sel!(parameterBufferSizeAndAlign)) }
699    }
700
701    // =========================================================================
702    // Methods
703    // =========================================================================
704
705    /// Get the physical size for a layer.
706    ///
707    /// C++ equivalent: `Size physicalSize(NS::UInteger layerIndex)`
708    #[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    /// Map physical coordinates to screen coordinates.
714    ///
715    /// C++ equivalent: `Coordinate2D mapPhysicalToScreenCoordinates(MTL::Coordinate2D physicalCoordinates, NS::UInteger layerIndex)`
716    #[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    /// Map screen coordinates to physical coordinates.
733    ///
734    /// C++ equivalent: `Coordinate2D mapScreenToPhysicalCoordinates(MTL::Coordinate2D screenCoordinates, NS::UInteger layerIndex)`
735    #[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    /// Copy parameter data to a buffer.
752    ///
753    /// C++ equivalent: `void copyParameterDataToBuffer(const MTL::Buffer* buffer, NS::UInteger offset)`
754    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// ============================================================================
804// Tests
805// ============================================================================
806
807#[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}