MTLBuffer contents pointer is nullable
objc2_metal:
/// Returns the data pointer of this buffer's shared copy.
#[unsafe(method(contents))]
#[unsafe(method_family = none)]
fn contents(&self) -> NonNull<c_void>;
Apple documentation:
A pointer to the shared copy of the buffer data, or NULL for buffers allocated with a private resource storage mode (MTLStorageModePrivate).
Damn. This is a bug in Apple's headers (the header is marked NS_ASSUME_NONNULL_BEGIN, so contents should have been opted out with some sort of __nullable). Swift is actually also affected by this, they map the pointer as UnsafeMutableRawPointer instead of UnsafeMutableRawPointer?.
It's unfortunately a breaking change for me to properly fix, and while you can sometimes argue that it's fine when it's done to fix soundness issues, this isn't really a soundness issue for consumers unless they use MTLStorageModePrivate.
I'll probably fix for now by checking internally on access whether the pointer is NULL.
Hmm, actually, I know that's what the docs say, but how are you observing this?
The small test below seems to indicate that the docs for contents are actually incorrect?
#!/usr/bin/env cargo -Z script
---
[package]
edition = "2024"
[dependencies]
objc2-metal = "0.3.2"
---
use objc2_metal::{MTLBuffer, MTLCreateSystemDefaultDevice, MTLDevice, MTLResourceOptions};
#[link(name = "CoreGraphics", kind = "framework")]
unsafe extern "C" {}
fn main() {
let device = MTLCreateSystemDefaultDevice().unwrap();
let buffer = device.newBufferWithLength_options(100, MTLResourceOptions::StorageModePrivate).unwrap();
println!("{:?}", buffer.contents());
}
See also https://github.com/gfx-rs/wgpu/issues/7357.
The small test below
I tried running this on both a Macbook Pro M2 running macOS 15.6.1, and on an older 2013-something Intel Macbook (integrated graphics card) running Mac OS X 10.12.6, and both return a pointer (and not NULL).
But maybe it's NULL when using an external graphics card?