Skip to main content

mtl_gpu/device/
residency_set.rs

1//! Residency set-related Device methods.
2//!
3//! Corresponds to residency set methods in `Metal/MTLDevice.hpp`.
4
5use std::ffi::c_void;
6
7use mtl_foundation::Referencing;
8use mtl_sys::{msg_send_2, sel};
9
10use super::Device;
11use crate::residency_set::{ResidencySet, ResidencySetDescriptor};
12
13impl Device {
14    /// Create a new residency set.
15    ///
16    /// C++ equivalent: `ResidencySet* newResidencySet(const MTL::ResidencySetDescriptor*, NS::Error**)`
17    pub fn new_residency_set(
18        &self,
19        descriptor: &ResidencySetDescriptor,
20    ) -> Result<ResidencySet, mtl_foundation::Error> {
21        unsafe {
22            let mut error: *mut c_void = std::ptr::null_mut();
23            let ptr: *mut c_void = msg_send_2(
24                self.as_ptr(),
25                sel!(newResidencySetWithDescriptor:error:),
26                descriptor.as_ptr(),
27                &mut error as *mut _,
28            );
29
30            if ptr.is_null() {
31                if !error.is_null() {
32                    return Err(
33                        mtl_foundation::Error::from_ptr(error).expect("error should be valid")
34                    );
35                }
36                return Err(mtl_foundation::Error::error(
37                    std::ptr::null_mut(),
38                    -1,
39                    std::ptr::null_mut(),
40                )
41                .expect("failed to create error"));
42            }
43
44            Ok(ResidencySet::from_raw(ptr).expect("failed to create residency set"))
45        }
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52    use crate::device::system_default;
53
54    #[test]
55    fn test_new_residency_set() {
56        let device = system_default().expect("no Metal device");
57        let descriptor = ResidencySetDescriptor::new().expect("failed to create descriptor");
58
59        // Creating a residency set should succeed
60        let result = device.new_residency_set(&descriptor);
61        assert!(result.is_ok());
62    }
63}