Source code

Revision control

Copy as Markdown

Other Tools

//! # Bindings to the `Metal` framework
//!
//! See [Apple's docs][apple-doc] and [the general docs on framework crates][framework-crates] for more information.
//!
//!
//! Metal has tools for validating that you're using it correctly, using these
//! is highly recommended! See [Apple's documentation on it][apple-doc], or
//! run `man MetalValidation` to get information on environment variables.
//!
//!
//! NOTE: To use [`MTLCreateSystemDefaultDevice`] you need to link to
//! `CoreGraphics`, this can be done by using `objc2-core-graphics`, or by
//! doing:
//! ```rust
//! #[link(name = "CoreGraphics", kind = "framework")]
//! extern "C" {}
//! ```
//!
#![cfg_attr(
not(feature = "MTLDevice"),
doc = "[`MTLCreateSystemDefaultDevice`]: #needs-MTLDevice-feature"
)]
//!
//! # Safety considerations
//!
//! Metal allows running arbitrary code on the GPU. We treat memory safety
//! issues on the GPU as just as unsafe as that which applies to the CPU. A
//! few notes on this below.
//!
//! ## Shaders
//!
//! Shaders are (often) written in an unsafe C-like language.
//!
//! Loading them (via `MTLLibrary`, function stitching etc.) is perfectly
//! safe, it is similar to dynamic linking. The restrictions that e.g.
//! `libloading::Library::new` labours under do not apply, since there are no
//! ctors in [the Metal Shading Language][msl-spec] (see section 4.2).
//!
//! Similarly, getting individual shaders (`MTLFunction`) is safe, we can
//! model this as the same as calling `dlsym` (which just returns a pointer).
//!
//! _Calling_ functions though, is not safe. Even though they can have their
//! parameter and return types checked at runtime, they may have additional
//! restrictions not present in the signature (e.g. `__builtin_unreachable()`
//! is possible in MSL, so is out-of-bounds accesses). If you view
//! `MTLFunction` as essentially just an `unsafe fn()` pointer, this should be
//! apparent.
//!
//!
//! ## Bounds checks
//!
//! It is yet unclear whether Metal APIs are bounds-checked on the CPU side or
//! not, so APIs that take offsets / lengths are often unsafe.
//!
//! ## Synchronization
//!
//! `MTLResource` subclasses such as `MTLBuffer` and `MTLTexture` require
//! synchronization between the CPU and the GPU, or between different threads
//! on the GPU itself, so APIs taking these are often unsafe.
//!
//! ## Memory management and lifetimes
//!
//! Resources used in `MTL4CommandBuffer`s or command buffers with created
//! with one of:
//! - `MTLCommandBufferDescriptor::setRetainedReferences(false)`.
//! - `MTLCommandQueue::commandBufferWithUnretainedReferences()`.
//!
//! Must be kept alive for as long as they're used.
//!
//! ## Type safety
//!
//! `MTLBuffer` is untyped (in a similar manner as a `[u8]` slice), you must
//! ensure that any usage of it is done with valid types.
#![recursion_limit = "256"]
#![allow(non_snake_case)]
#![no_std]
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
#![cfg_attr(docsrs, feature(doc_cfg))]
// Update in Cargo.toml as well.
#![doc(html_root_url = "https://docs.rs/objc2-metal/0.3.2")]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "MTLAccelerationStructureTypes")]
mod acceleration_structure_types;
#[cfg(feature = "MTLCaptureManager")]
mod capture;
#[cfg(feature = "MTLCounters")]
mod counters;
#[cfg(feature = "MTLDevice")]
mod device;
mod generated;
#[cfg(feature = "unstable-private")]
mod private;
#[cfg(feature = "MTLRasterizationRate")]
mod rasterization_rate;
#[cfg(feature = "MTLResource")]
mod resource;
mod slice;
#[cfg(feature = "MTLTexture")]
mod texture;
#[cfg(feature = "MTLTypes")]
mod types;
#[cfg(feature = "MTLAccelerationStructureTypes")]
pub use self::acceleration_structure_types::MTLPackedFloat3;
#[cfg(feature = "MTLCounters")]
pub use self::counters::*;
#[cfg(feature = "MTLDevice")]
pub use self::device::*;
#[allow(unused_imports, unreachable_pub)]
pub use self::generated::*;
#[cfg(feature = "unstable-private")]
pub use self::private::MTLDevicePrivate;
#[cfg(feature = "MTLResource")]
pub use self::resource::*;
#[cfg(all(feature = "MTLRenderCommandEncoder", feature = "MTLCommandEncoder"))]
pub use self::slice::MTLRenderCommandEncoderSliceExt;
#[cfg(feature = "MTLTexture")]
pub use self::texture::*;