Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 113 additions & 1 deletion framework-crates/objc2-metal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,109 @@
doc = "[`MTLDevice::newLibraryWithSource_options_error`]: #needs-MTLDevice-feature"
)]
//!
//! # Metal 4 Support
//!
//! This crate includes comprehensive support for Metal 4, introduced at WWDC 2025.
//! Metal 4 provides significant new features including:
//!
//! - **Shader Direct Inference**: ML inference directly in Metal shaders
//! - **Explicit Memory Management**: Direct control via [`MTL4CommandAllocator`]
//! - **New Core APIs**: [`MTL4CommandQueue`], [`MTL4CommandBuffer`], [`MTL4Compiler`], etc.
//!
#![cfg_attr(
not(feature = "std"),
doc = "[`MTL4CommandAllocator`]: #needs-std-feature"
)]
//!
//! ## Version Requirements
//!
//! Metal 4 requires specific OS versions:
//!
//! - macOS 26.0+ (Tahoe)
//! - iOS 26.0+
//! - iPadOS 26.0+
//! - tvOS 26.0+
//! - visionOS 26.0+
//!
//! ## Availability Detection
//!
//! Always check for Metal 4 availability at runtime, as not all devices support it:
#![cfg_attr(
feature = "std",
doc = r##"
//! ```no_run
//! use objc2_metal::metal4_detection;
//!
//! if metal4_detection::is_metal4_available() {
//! // Use Metal 4 features
//! } else {
//! // Fall back to earlier Metal versions
//! }
//! ```
//! "##
)]
//!
#![cfg_attr(
not(feature = "std"),
doc = "//! ```ignore\n//! // Metal 4 detection requires the `std` feature\n//! ```\n"
)]
//!
//! Or use the [`available!`] macro for more granular control:
//!
//! ```no_run
//! use objc2::available;
//!
//! if available!(macos = 26.0, ios = 26.0, tvos = 26.0, visionos = 26.0) {
//! // Use Metal 4 features
//! } else {
//! // Fall back to earlier Metal versions
//! }
//! ```
//!
#![cfg_attr(
not(feature = "std"),
doc = "[`available!`]: https://docs.rs/objc2/latest/objc2/macro.available.html"
)]
//!
#![cfg_attr(
feature = "std",
doc = r##"//! [`available!`]: https://docs.rs/objc2/latest/objc2/macro.available.html
//! "##
)]
//!
//! ## Metal 4 Types
//!
//! The following Metal 4 types are available when the corresponding features are enabled:
//!
//! - **Command Pipeline**: [`MTL4CommandQueue`], [`MTL4CommandBuffer`], [`MTL4CommandAllocator`], [`MTL4CommandEncoder`]
//! - **Rendering**: [`MTL4RenderCommandEncoder`], [`MTL4RenderPass`], [`MTL4RenderPipeline`]
//! - **Compute**: [`MTL4ComputeCommandEncoder`], [`MTL4ComputePipeline`]
//! - **Compilation**: [`MTL4Compiler`], [`MTL4CompilerTask`], [`MTL4FunctionDescriptor`]
//! - **Resources**: [`MTL4ArgumentTable`], [`MTL4BufferRange`], [`MTL4AccelerationStructure`]
//! - **Machine Learning**: [`MTL4MachineLearningCommandEncoder`], [`MTL4MachineLearningPipeline`]
//!
#![cfg_attr(
not(any(
feature = "MTL4CommandQueue",
feature = "MTL4CommandBuffer",
feature = "MTL4CommandAllocator",
feature = "MTL4Compiler"
)),
doc = "//! [`MTL4CommandQueue`]: #needs-MTL4CommandQueue-feature\n"
)]
//!
#![cfg_attr(
not(feature = "std"),
doc = r##"//! See [`metal4_detection`] module for runtime detection utilities.
//! "##
)]
//!
#![cfg_attr(
feature = "std",
doc = r##"//! See [`metal4_detection`] module for comprehensive runtime detection utilities.
//! "##
)]
//!
//! # Safety considerations
//!
//! Metal allows running arbitrary code on the GPU. We treat memory safety
Expand Down Expand Up @@ -99,7 +202,8 @@
#![recursion_limit = "256"]
#![allow(non_snake_case)]
#![no_std]
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
// Disabled so `--all-features` works on stable Rust.
// #![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")]
Expand All @@ -119,6 +223,10 @@ mod counters;
#[cfg(feature = "MTLDevice")]
mod device;
mod generated;

// Metal 4 detection utilities (always available when std feature is enabled)
#[cfg(feature = "std")]
pub mod metal4_detection;
#[cfg(feature = "unstable-private")]
mod private;
#[cfg(feature = "MTLRasterizationRate")]
Expand All @@ -137,8 +245,12 @@ pub use self::acceleration_structure_types::MTLPackedFloat3;
pub use self::counters::*;
#[cfg(feature = "MTLDevice")]
pub use self::device::*;

// Re-export Metal 4 detection utilities
#[allow(unused_imports, unreachable_pub)]
pub use self::generated::*;
#[cfg(feature = "std")]
pub use self::metal4_detection::*;
#[cfg(feature = "unstable-private")]
pub use self::private::MTLDevicePrivate;
#[cfg(feature = "MTLResource")]
Expand Down
198 changes: 198 additions & 0 deletions framework-crates/objc2-metal/src/metal4_detection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
//! Metal 4 detection utilities.
//!
//! This module provides utilities for detecting Metal 4 availability.
//!
//! # Metal 4 Requirements
//!
//! Metal 4 was introduced at WWDC 2025 and requires specific OS versions:
//!
//! - macOS 26.0+ (Tahoe)
//! - iOS 26.0+
//! - iPadOS 26.0+
//! - tvOS 26.0+
//! - visionOS 26.0+
//!
//! # Usage Pattern
//!
//! To use Metal 4 APIs safely, you should check for availability at runtime
//! using the [`available!`] macro from the `objc2` crate:
//!
//! ```no_run
//! use objc2::available;
//!
//! if available!(macos = 26.0, ios = 26.0, tvos = 26.0, visionos = 26.0) {
//! // Use Metal 4 features like MTL4CommandQueue, MTL4FXFrameInterpolator, etc.
//! } else {
//! // Fall back to earlier Metal versions
//! }
//! ```

/// Metal 4 OS version requirements.
///
/// These constants define the minimum OS versions required for Metal 4 support.
/// Use these with the [`available!`] macro to check for Metal 4 availability.
///
///
/// # Examples
///
/// ```no_run
/// use objc2_metal::metal4_detection::METAL4_MACOS_VERSION;
///
/// assert_eq!(METAL4_MACOS_VERSION, 26.0);
/// ```

pub const METAL4_MACOS_VERSION: f64 = 26.0;
pub const METAL4_IOS_VERSION: f64 = 26.0;
pub const METAL4_TVOS_VERSION: f64 = 26.0;
pub const METAL4_VISIONOS_VERSION: f64 = 26.0;

/// Runtime check for Metal 4 availability on the current OS.
///
/// This uses objc2's [`available!`] macro and should be preferred over
/// platform-only checks when gating Metal 4 API usage.
#[must_use]
#[inline]
pub fn is_metal4_available() -> bool {
objc2::available!(macos = 26.0, ios = 26.0, tvos = 26.0, visionos = 26.0)
}

/// Check if the current platform is likely to support Metal 4.
///
/// This is a **compile-time only** check that returns `true` if the target
/// platform is one of the platforms that support Metal 4. This does **not**
/// check the actual OS version at runtime.
///
/// # Returns
///
/// `true` if the target platform is macOS, iOS, tvOS, or visionOS.
///
///
/// # Examples
///
/// ```no_run
/// use objc2_metal::metal4_detection::is_metal4_platform;
///
/// if is_metal4_platform() {
/// println!("Running on a platform that supports Metal 4");
/// }
/// ```
///
/// # Note
///
/// This function only checks the target platform, not the actual OS version.
/// For runtime version checking, use the [`available!`] macro instead.
#[must_use]
#[inline]
pub const fn is_metal4_platform() -> bool {
cfg!(any(
target_os = "macos",
target_os = "ios",
target_os = "tvos",
target_os = "visionos"
))
}

/// Metal 4 feature set information.
///
/// This struct provides information about which Metal 4 features are
/// supported in the current SDK.
///
///
/// # Examples
///
/// ```no_run
/// use objc2_metal::metal4_detection::Metal4Features;
///
/// let features = Metal4Features::current();
/// println!("Metal 4 types available: {}", features.has_metal4_types);
/// ```
#[derive(Debug, Clone, Copy, Default)]
pub struct Metal4Features {
/// Whether Metal 4 types are available in the SDK
pub has_metal4_types: bool,
/// Whether the platform supports Metal 4
pub is_supported_platform: bool,
}

impl Metal4Features {
/// Get information about Metal 4 features in the current SDK.
///
/// This function provides compile-time information about which Metal 4
/// features are available in the current SDK and target platform.
///
/// # Examples
///
/// ```no_run
/// use objc2_metal::metal4_detection::Metal4Features;
///
/// let features = Metal4Features::current();
/// if features.has_metal4_types && features.is_supported_platform {
/// println!("Metal 4 is available in the current SDK");
/// }
/// ```
#[must_use]
#[inline]
pub const fn current() -> Self {
Self {
// Metal 4 types are available if the corresponding features are enabled
has_metal4_types: cfg!(any(
feature = "MTL4CommandQueue",
feature = "MTL4CommandBuffer",
feature = "MTL4Compiler"
)),
// Platform support check
is_supported_platform: is_metal4_platform(),
}
}

/// Check if all Metal 4 features are available.
///
/// # Examples
///
/// ```no_run
/// use objc2_metal::metal4_detection::Metal4Features;
///
/// let features = Metal4Features::current();
/// if features.has_all_features() {
/// println!("All Metal 4 features are available!");
/// }
/// ```
#[must_use]
#[inline]
pub const fn has_all_features(&self) -> bool {
self.has_metal4_types && self.is_supported_platform
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_version_constants() {
assert_eq!(METAL4_MACOS_VERSION, 26.0);
assert_eq!(METAL4_IOS_VERSION, 26.0);
assert_eq!(METAL4_TVOS_VERSION, 26.0);
assert_eq!(METAL4_VISIONOS_VERSION, 26.0);
}

#[test]
fn test_platform_check() {
// This will be true or false depending on the compilation target
let _ = is_metal4_platform();
}

#[test]
fn test_runtime_check() {
let _ = is_metal4_available();
}

#[test]
fn test_features_struct() {
let features = Metal4Features::current();
// Just verify the struct can be created and accessed
let _ = features.has_metal4_types;
let _ = features.is_supported_platform;
let _ = features.has_all_features();
}
}
9 changes: 2 additions & 7 deletions framework-crates/objc2-metal/src/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,8 @@ impl MTLRenderPipelineReflection {
);
}

#[cfg(feature = "MTLSampler")]
impl MTLSamplerDescriptor {
extern_methods!(
#[unsafe(method(setLodBias:))]
pub unsafe fn setLodBias(&self, bias: f32);
);
}
// setLodBias is now defined in the generated MTLSampler.rs file
// This duplicate definition has been removed to fix compilation error

#[cfg(feature = "MTLVertexDescriptor")]
impl MTLVertexDescriptor {
Expand Down
Loading
Loading