use gpu_allocator::metal::{AllocationCreateDesc, Allocator, AllocatorCreateDesc}; use log::info; use objc2_foundation::NSArray; use objc2_metal::{ MTLCreateSystemDefaultDevice, MTLDevice as _, MTLHeap, MTLPixelFormat, MTLPrimitiveAccelerationStructureDescriptor, MTLStorageMode, MTLTextureDescriptor, }; fn main() { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("trace")).init(); // Allow the innards of objc2-metal to link the static function below: // https://docs.rs/objc2-metal/0.2.2/objc2_metal/index.html #[link(name = "CoreGraphics", kind = "framework")] extern "C" {} let device = MTLCreateSystemDefaultDevice().expect("No MTLDevice found"); // Setting up the allocator let mut allocator = Allocator::new(&AllocatorCreateDesc { device: device.clone(), debug_settings: Default::default(), allocation_sizes: Default::default(), create_residency_set: false, }) .unwrap(); // Test allocating Gpu Only memory { let allocation_desc = AllocationCreateDesc::buffer( &device, "Test allocation (Gpu Only)", 512, gpu_allocator::MemoryLocation::GpuOnly, ); let allocation = allocator.allocate(&allocation_desc).unwrap(); // SAFETY: We will only allocate objects on this heap within the returned offset and size let heap = unsafe { allocation.heap() }; let buffer = unsafe { heap.newBufferWithLength_options_offset( allocation.size() as usize, heap.resourceOptions(), allocation.offset() as usize, ) } .unwrap(); drop(buffer); allocator.free(&allocation).unwrap(); info!("Allocation and deallocation of GpuOnly memory was successful."); } // Test allocating Cpu to Gpu memory { let allocation_desc = AllocationCreateDesc::buffer( &device, "Test allocation (Cpu to Gpu)", 512, gpu_allocator::MemoryLocation::CpuToGpu, ); let allocation = allocator.allocate(&allocation_desc).unwrap(); // SAFETY: We will only allocate objects on this heap within the returned offset and size let heap = unsafe { allocation.heap() }; let buffer = unsafe { heap.newBufferWithLength_options_offset( allocation.size() as usize, heap.resourceOptions(), allocation.offset() as usize, ) } .unwrap(); drop(buffer); allocator.free(&allocation).unwrap(); info!("Allocation and deallocation of CpuToGpu memory was successful."); } // Test allocating Gpu to Cpu memory { let allocation_desc = AllocationCreateDesc::buffer( &device, "Test allocation (Gpu to Cpu)", 512, gpu_allocator::MemoryLocation::GpuToCpu, ); let allocation = allocator.allocate(&allocation_desc).unwrap(); // SAFETY: We will only allocate objects on this heap within the returned offset and size let heap = unsafe { allocation.heap() }; let buffer = unsafe { heap.newBufferWithLength_options_offset( allocation.size() as usize, heap.resourceOptions(), allocation.offset() as usize, ) } .unwrap(); drop(buffer); allocator.free(&allocation).unwrap(); info!("Allocation and deallocation of GpuToCpu memory was successful."); } // Test allocating texture { let texture_desc = unsafe { MTLTextureDescriptor::new() }; texture_desc.setPixelFormat(MTLPixelFormat::RGBA8Unorm); unsafe { texture_desc.setWidth(64) }; unsafe { texture_desc.setHeight(64) }; texture_desc.setStorageMode(MTLStorageMode::Private); let allocation_desc = AllocationCreateDesc::texture(&device, "Test allocation (Texture)", &texture_desc); let allocation = allocator.allocate(&allocation_desc).unwrap(); // SAFETY: We will only allocate objects on this heap within the returned offset and size let heap = unsafe { allocation.heap() }; let buffer = unsafe { heap.newTextureWithDescriptor_offset(&texture_desc, allocation.offset() as usize) } .unwrap(); drop(buffer); allocator.free(&allocation).unwrap(); info!("Allocation and deallocation of Texture was successful."); } // Test allocating acceleration structure { let empty_array = NSArray::from_slice(&[]); let acc_desc = MTLPrimitiveAccelerationStructureDescriptor::descriptor(); acc_desc.setGeometryDescriptors(Some(&empty_array)); let sizes = device.accelerationStructureSizesWithDescriptor(&acc_desc); let allocation_desc = AllocationCreateDesc::acceleration_structure_with_size( &device, "Test allocation (Acceleration structure)", sizes.accelerationStructureSize as u64, gpu_allocator::MemoryLocation::GpuOnly, ); let allocation = allocator.allocate(&allocation_desc).unwrap(); // SAFETY: We will only allocate objects on this heap within the returned offset and size let heap = unsafe { allocation.heap() }; let buffer = unsafe { heap.newAccelerationStructureWithSize_offset( allocation.size() as usize, allocation.offset() as usize, ) } .unwrap(); drop(buffer); allocator.free(&allocation).unwrap(); info!("Allocation and deallocation of Acceleration structure was successful."); } }