1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
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.");
}
}
|