Metal is a low-level graphics and compute API from Apple, providing direct access to the GPU on iOS, macOS and tvOS. It replaces OpenGL and OpenCL, offering minimal CPU overhead and predictable performance. According to Apple WWDC (2025), Metal is used in 98% of applications with GPU rendering in the Apple ecosystem.
Key Takeaways
Metal is a low-level API for working with the graphics processing unit (GPU), introduced by Apple in 2014 alongside iOS 8 and OS X Yosemite. Metal was created as a replacement for OpenGL and OpenCL with the goal of reducing CPU overhead and providing more direct access to GPU hardware on Apple devices.
Unlike OpenGL, where the driver performs many checks and transformations on the CPU, Metal uses an explicit resource management model. The developer controls memory allocation, synchronization and GPU command submission, delivering up to 50% performance improvement over OpenGL ES on the same hardware.
Metal supports all Apple chips from A7 (2013) to M4 Ultra (2025). The API is constantly evolving: Metal 3 (2022) added mesh shaders and ray tracing support, Metal 3.1 (2023) — fast resource sharing between CPU and GPU, and Metal 4 (2025) — hardware acceleration of neural networks on GPU with FP8 and INT4 support.
The first version of Metal (2014) provided a basic API for graphics rendering on iOS. Metal 2 (2017) added compute shaders and Metal Performance Shaders. Metal 3 (2022) introduced MetalFX Upscaling — Apple's own upscaling for games, competing with NVIDIA DLSS and AMD FSR. MetalFX delivers up to 2x performance improvement on Mac with M2.
Metal 4 (2025) focused on machine learning and ray tracing. According to Apple (2025), Metal 4 on M4 Ultra delivers up to 80 TFLOPS in compute tasks at FP16 and supports hardware AV1 decoding. Metal is now also supported on Apple Vision Pro through the compositor service for rendering immersive content.
Metal Architecture is built around the concept of explicit management: the developer creates MTLDevice objects (device), MTLBuffer (data buffers), MTLTexture (textures) and MTLCommandQueue (command queue). Unlike OpenGL, where state is stored in the context, Metal uses state objects that are compiled in advance.
MTLDevice represents a physical or virtual GPU. All Metal resources are created through this object: buffers, textures, shader libraries, pipelines. On systems with multiple GPUs (Mac Pro) a specific device can be selected. The supportsFamily: method checks for feature support: ray tracing, mesh shaders, MetalFX.
import Metal
// Getting the GPU device
guard let device = MTLCreateSystemDefaultDevice() else {
fatalError("Metal not supported")
}
// Checking capabilities
let supportsRayTracing = device.supportsFamily(.metal3)
let gpuName = device.name // "Apple M4 Pro"
let maxBufferSize = device.maxBufferLength
The maxBufferLength property determines the maximum buffer size supported by the device. On Apple Silicon with Unified Memory the limit is up to 128 GB (on M4 Ultra). This allows working with large datasets for ML and scientific computing without buffer segmentation. The device also manages the memory pool through MTLHeap.
MTLBuffer — a contiguous memory region accessible by the GPU. Buffers are used for vertex data, matrices, uniform variables. Modes: shared (CPU + GPU access on unified memory), private (GPU only, faster), managed (for discrete GPUs, with synchronization). On Apple Silicon shared mode is recommended for simplicity.
MTLTexture — a multi-dimensional pixel array for textures and render targets. Supports 1D, 2D, 3D, cube and array textures. Formats: RGBA8Unorm, BGRA8Unorm, RGBA16Float, R32Float, ASTC (compressed), depth (depth32Float) and stencil. Texture Usage flags indicate how the texture will be used: rendering, shader reading, copying.
MTLLibrary — a collection of compiled GPU functions (shaders). A library can be created from MSL (Metal Shading Language) source code at runtime or precompiled and included in the bundle (.metallib). Precompilation is recommended to eliminate initialization delays.
MTLFunction represents a specific shader function. Vertex shaders, fragment shaders, compute kernels and mesh shaders are created through the library. Functions are cached on the GPU and reused between frames. Shader arguments are passed through buffers and texture slots with index-based binding.
Rendering in Metal is organized through asynchronous command queues. The developer creates MTLCommandBuffer, encodes rendering or compute commands into it, and submits it to MTLCommandQueue. The GPU executes commands sequentially while the CPU can continue working. Synchronization happens through semaphores or completionHandler.
MTLCommandQueue — a command queue created from MTLDevice. An application can have multiple queues for graphics, compute and copy operations. Each queue guarantees sequential command execution. MTLCommandBuffer — a container for one batch of GPU work. After encoding, it is committed and executed on the GPU.
// Main render loop
let commandQueue = device.makeCommandQueue()!
guard let commandBuffer = commandQueue.makeCommandBuffer()
else { return }
guard let descriptor = currentDrawable.texture.makeRenderPassDescriptor(
attachment: 0
) else { return }
let encoder = commandBuffer.makeRenderCommandEncoder(
descriptor: descriptor
)!
encoder.setRenderPipelineState(pipelineState)
encoder.drawPrimitives(type: .triangle,
vertexStart: 0, vertexCount: 36)
encoder.endEncoding()
commandBuffer.present(currentDrawable)
commandBuffer.commit()
The drawPrimitives method executes geometry rendering. The vertexCount parameter specifies the number of vertices. A new command buffer is created for each frame. Present synchronizes rendering with the display's VSync. Metal automatically manages display synchronization through CAMetalLayer.
MTLRenderPipelineState — a compiled rendering pipeline state, including vertex and fragment shaders, depth-stencil configuration, blending and output pixel format. Creating a pipeline state is an expensive operation, so objects are cached and reused. Different pipeline states are created for different shader combinations.
Metal 3.1 introduced fast rendering through Immutable Samplers that are cached on the GPU to accelerate texture sampling. Metal supports up to 31 textures per shader slot on Apple Silicon. On older devices with A13 and below the limit is reduced to 16 slots. It is recommended to combine textures into Texture Atlases to reduce the number of samples.
Metal Shading Language (MSL) is a shader programming language based on C++14 with extensions for GPU computing. MSL supports templates, function overloading, namespaces and address arithmetic. Shaders are compiled into binary GPU code through Apple's LLVM backend.
Vertex shader processes each vertex: transforms coordinates from world space to screen space, computes normals and passes data to the fragment shader. Fragment shader computes the color of each pixel: applies textures, lighting and post-processing effects.
// Metal vertex shader
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
float3 position [[attribute(0)]];
float3 normal [[attribute(1)]];
};
struct VertexOut {
float4 position [[position]];
float3 worldNormal;
};
vertex VertexOut vertexMain(
VertexIn in [[stage_in]],
constant float4x4 &mvp [[buffer(0)]]
) {
VertexOut out;
out.position = mvp * float4(in.position, 1.0);
out.worldNormal = in.normal;
return out;
}
[[attribute(N)]] attributes correspond to vertex formats specified in MTLVertexDescriptor. The [buffer(0)] buffer passes the MVP matrix as a uniform variable. The vertex position must be marked with [[position]] for passing to the rasterizer. All MSL vector types — float2, float3, float4 — map to GPU hardware registers.
Compute shader (kernel) is a GPU function executed outside the graphics pipeline. Kernel functions are marked with the kernel qualifier and execute in threads organized into threadgroups. Compute shaders are used for image processing, physics simulation, ML and post-processing.
// Compute kernel for image blur
kernel void blurKernel(
texture2d<half> input [[texture(0)]],
texture2d<half> output [[texture(1)]],
constant float &radius [[buffer(0)]],
uint2 gid [[thread_position_in_grid]]
) {
if (gid.x >= input.get_width() ||
gid.y >= input.get_height()) { return; }
half4 color = input.read(gid);
output.write(color, gid);
}
The gid [[thread_position_in_grid]] parameter contains the unique thread index. Texture2D<type> is specialized by pixel type: half (FP16), float (FP32). Compute kernels can be launched with a grid size of over 1 billion threads on M4 Ultra. The maximum threadgroup size is 1024 threads on Apple Silicon GPUs.
Metal Performance Shaders (MPS) is a library of optimized GPU functions provided by Apple. MPS includes convolutional neural networks (MPSNNConvolution), matrix multiplication (MPSMatrixMultiplication), sorting (MPSParallelSort) and image processing (MPSImageGaussianBlur). All functions are optimized for specific Apple GPUs.
MetalFX is an upscaling and anti-aliasing technology, competing with NVIDIA DLSS and AMD FSR. MetalFX offers two modes: Spatial (spatial upscaling via FSR 2 algorithm) and Temporal (temporal upscaling with motion vectors). Temporal MetalFX delivers quality close to native 4K from a 1440p render.
According to Apple (2025), MetalFX Temporal on M4 Max delivers up to 3x performance improvement in games while maintaining visually indistinguishable quality from native resolution. MetalFX works on any GPU supporting Metal 3, without dedicated tensor cores. Integrating MetalFX into a project takes about 50 lines of code.
Ray Tracing in Metal 3 is supported on M3, M4 and A17 Pro chips with hardware acceleration units (Ray Tracing Accelerators). Metal provides MTLAccelerationStructure for building BVH and MTLIntersectionFunction for ray intersection in shaders. Massive scenes with millions of triangles are compiled into BVH in milliseconds.
According to Apple (2025), hardware ray tracing on M4 Ultra performs up to 40 billion ray intersections per second (Giga rays/s). This is 4 times faster than software ray tracing on M1 Ultra. Metal RT supports intersection queries, dynamic geometry and Motion Blur for realistic animations. Reflections and shadows with ray tracing run in real-time at 60 FPS.
Unified Memory is the Apple Silicon architecture where CPU and GPU share the same physical memory. Metal on Apple Silicon does not require copying data between CPU and GPU: MTLBuffer in shared mode is accessible to both processors without copying. This eliminates the main bottleneck of traditional GPUs (PCIe transfers).
Zero-Copy in Metal allows the CPU to write data to a buffer and the GPU to read it without delays. According to Apple (2025), this delivers 30–50% performance improvement over discrete GPUs on games and ML tasks. For discrete GPUs (Mac Pro with Radeon) Metal supports managed mode with automatic synchronization through memory barriers.
Frequently Asked Questions
Metal is Apple's low-level GPU API providing minimal CPU overhead. It is used for 3D graphics, ML computations, image processing and simulations on iOS, macOS and tvOS. It replaces OpenGL and OpenCL.
Metal only works on Apple devices, integrated with Unified Memory and Metal Performance Shaders. Vulkan is a cross-platform API for Windows, Android and Linux. Both APIs are comparable in performance, but Metal has lower overhead on Apple Silicon.
Yes, with Metal 3 on M3, M4 and A17 Pro chips hardware ray tracing is available. Metal provides MTLAccelerationStructure and intersection query support in shaders. Performance — up to 40 Giga rays/s on M4 Ultra.
MetalFX is Apple's upscaling technology with Spatial and Temporal modes. It works on any GPU with Metal 3, without tensor cores. Delivers up to 3x performance improvement with quality close to native 4K on M4 Max.
The entry barrier is higher than SceneKit or Unity due to low-level resource management. Apple provides Metal Sample Code and tutorials at developer.apple.com. Basic triangle rendering requires about 200 lines of code.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also