mtl_gpu/device/heap.rs
1//! Device heap creation methods.
2//!
3//! Corresponds to heap creation methods in `Metal/MTLDevice.hpp`.
4
5use std::ffi::c_void;
6
7use mtl_foundation::Referencing;
8use mtl_sys::{msg_send_1, sel};
9
10use super::Device;
11use crate::error::ValidationError;
12use crate::heap::{Heap, HeapDescriptor};
13
14impl Device {
15 // =========================================================================
16 // Heap Creation
17 // =========================================================================
18
19 /// Create a new heap with the specified descriptor.
20 ///
21 /// C++ equivalent: `Heap* newHeap(const HeapDescriptor*)`
22 pub fn new_heap(&self, descriptor: &HeapDescriptor) -> Option<Heap> {
23 unsafe {
24 let ptr: *mut c_void = msg_send_1(
25 self.as_ptr(),
26 sel!(newHeapWithDescriptor:),
27 descriptor.as_ptr(),
28 );
29 Heap::from_raw(ptr)
30 }
31 }
32
33 /// Create a heap with validation.
34 ///
35 /// This safe method validates the descriptor before calling Metal APIs:
36 /// - Ensures heap size is > 0
37 ///
38 /// # Example
39 ///
40 /// ```ignore
41 /// let desc = HeapDescriptor::new().unwrap();
42 /// desc.set_size(1024 * 1024); // 1 MB
43 /// desc.set_storage_mode(StorageMode::PRIVATE);
44 ///
45 /// match device.new_heap_validated(&desc) {
46 /// Ok(heap) => { /* use heap */ }
47 /// Err(ValidationError::InvalidHeapSize) => { /* handle error */ }
48 /// Err(e) => { /* handle other errors */ }
49 /// }
50 /// ```
51 pub fn new_heap_validated(&self, descriptor: &HeapDescriptor) -> Result<Heap, ValidationError> {
52 // Validate size
53 if descriptor.size() == 0 {
54 return Err(ValidationError::InvalidHeapSize);
55 }
56
57 // Call existing safe implementation
58 self.new_heap(descriptor)
59 .ok_or(ValidationError::CreationFailed(None))
60 }
61
62 /// Create a new heap with a raw descriptor pointer.
63 ///
64 /// C++ equivalent: `Heap* newHeap(const HeapDescriptor*)`
65 ///
66 /// # Safety
67 ///
68 /// The descriptor pointer must be valid.
69 pub unsafe fn new_heap_with_ptr(&self, descriptor: *const c_void) -> Option<Heap> {
70 unsafe {
71 let ptr: *mut c_void =
72 msg_send_1(self.as_ptr(), sel!(newHeapWithDescriptor:), descriptor);
73 Heap::from_raw(ptr)
74 }
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use crate::device::system_default;
82 use crate::enums::StorageMode;
83
84 #[test]
85 fn test_new_heap() {
86 let device = system_default().expect("no Metal device");
87 let descriptor = HeapDescriptor::new().expect("failed to create descriptor");
88
89 descriptor.set_size(1024 * 1024); // 1 MB
90 descriptor.set_storage_mode(StorageMode::PRIVATE);
91
92 let heap = device.new_heap(&descriptor);
93 assert!(heap.is_some());
94
95 let heap = heap.unwrap();
96 assert!(heap.size() >= 1024 * 1024);
97 }
98}