Metal — cos'è, API grafica e shader

Autore: IT Sectr Pubblicato: 2026-05-03 Tempo di lettura: 10 min

Metal è un'API grafica e di calcolo a basso livello di Apple, che fornisce accesso diretto alla GPU su iOS, macOS e tvOS. Sostituisce OpenGL e OpenCL, offrendo un overhead minimo della CPU e prestazioni prevedibili. Secondo Apple WWDC (2025), Metal è utilizzato nel 98% delle applicazioni con rendering GPU nell'ecosistema Apple.

Punti Chiave

  • Metal — API GPU a basso livello di Apple con supporto per grafica e calcolo
  • MTLDevice — astrazione della GPU attraverso cui vengono create tutte le risorse Metal
  • Buffer di comandi MTLCommandBuffer consentono la registrazione multithread dei comandi
  • Shader Metal Shading Language compilano in codice GPU basato su C++14
  • Metal Performance Shaders forniscono funzioni GPU ottimizzate per ML e filtraggio

Cos'è Metal?

Metal è un'API a basso livello per lavorare con l'unità di elaborazione grafica (GPU), presentata da Apple nel 2014 insieme a iOS 8 e OS X Yosemite. Metal è stato creato come sostituto di OpenGL e OpenCL con l'obiettivo di ridurre l'overhead della CPU e fornire un accesso più diretto all'hardware della GPU sui dispositivi Apple.

A differenza di OpenGL, dove il driver esegue molti controlli e trasformazioni sulla CPU, Metal utilizza un modello di gestione esplicita delle risorse. Lo sviluppatore controlla l'allocazione della memoria, la sincronizzazione e l'invio dei comandi alla GPU, offrendo un miglioramento delle prestazioni fino al 50% rispetto a OpenGL ES sullo stesso hardware.

Metal supporta tutti i chip Apple dall'A7 (2013) al M4 Ultra (2025). L'API si evolve costantemente: Metal 3 (2022) ha aggiunto il supporto per mesh shader e ray tracing, Metal 3.1 (2023) — la condivisione rapida delle risorse tra CPU e GPU, e Metal 4 (2025) — l'accelerazione hardware delle reti neurali sulla GPU con supporto FP8 e INT4.

Storia di Metal

La prima versione di Metal (2014) forniva un'API di base per il rendering grafico su iOS. Metal 2 (2017) ha aggiunto i compute shader e Metal Performance Shaders. Metal 3 (2022) ha introdotto MetalFX Upscaling — l'upscaling proprietario di Apple per i giochi, concorrente di NVIDIA DLSS e AMD FSR. MetalFX offre fino a 2x di miglioramento delle prestazioni su Mac con M2.

Metal 4 (2025) si è concentrato sull'apprendimento automatico e il ray tracing. Secondo Apple (2025), Metal 4 su M4 Ultra raggiunge fino a 80 TFLOPS in attività di calcolo in FP16 e supporta la decodifica hardware AV1. Metal ora è supportato anche su Apple Vision Pro attraverso il servizio compositor per il rendering di contenuti immersivi.

Architettura Metal: Dispositivo e Risorse

L'architettura Metal è costruita attorno al concetto di gestione esplicita: lo sviluppatore crea oggetti MTLDevice (dispositivo), MTLBuffer (buffer di dati), MTLTexture (texture) e MTLCommandQueue (coda di comandi). A differenza di OpenGL, dove lo stato è memorizzato nel contesto, Metal utilizza oggetti di stato compilati in anticipo.

MTLDevice — Punto di Ingresso dell'API

MTLDevice rappresenta una GPU fisica o virtuale. Tutte le risorse Metal vengono create tramite questo oggetto: buffer, texture, librerie di shader, pipeline. Su sistemi con più GPU (Mac Pro) è possibile selezionare un dispositivo specifico. Il metodo supportsFamily: verifica il supporto delle funzionalità: ray tracing, mesh shader, MetalFX.

swift
import Metal
 
// Ottenimento del dispositivo GPU
guard let device = MTLCreateSystemDefaultDevice() else {
    fatalError("Metal non supportato")
}
 
// Verifica delle capacità
let supportsRayTracing = device.supportsFamily(.metal3)
let gpuName = device.name // "Apple M4 Pro"
let maxBufferSize = device.maxBufferLength

La proprietà maxBufferLength determina la dimensione massima del buffer supportata dal dispositivo. Su Apple Silicon con Unified Memory il limite arriva fino a 128 GB (su M4 Ultra). Ciò consente di lavorare con grandi set di dati per ML e calcolo scientifico senza segmentazione dei buffer. Il dispositivo gestisce anche il pool di memoria attraverso MTLHeap.

MTLBuffer e MTLTexture — Dati per la GPU

MTLBuffer — una regione di memoria contigua accessibile dalla GPU. I buffer vengono utilizzati per dati dei vertici, matrici, variabili uniform. Modalità: shared (accesso CPU + GPU su memoria unificata), private (solo GPU, più veloce), managed (per GPU discrete, con sincronizzazione). Su Apple Silicon si consiglia la modalità shared per semplicità.

MTLTexture — un array multidimensionale di pixel per texture e render target. Supporta texture 1D, 2D, 3D, cube e array. Formati: RGBA8Unorm, BGRA8Unorm, RGBA16Float, R32Float, ASTC (compresso), profondità (depth32Float) e stencil. I flag Texture Usage indicano come verrà utilizzata la texture: rendering, lettura shader, copia.

MTLLibrary e Compilazione degli Shader

MTLLibrary — una raccolta di funzioni GPU compilate (shader). Una libreria può essere creata dal codice sorgente MSL (Metal Shading Language) in fase di esecuzione o precompilata e inclusa nel bundle (.metallib). Si consiglia la precompilazione per eliminare i ritardi di inizializzazione.

MTLFunction rappresenta una specifica funzione shader. Vertex shader, fragment shader, compute kernel e mesh shader vengono creati tramite la libreria. Le funzioni vengono memorizzate nella cache della GPU e riutilizzate tra i fotogrammi. Gli argomenti degli shader vengono passati tramite buffer e slot di texture con associazione basata su indice.

Rendering con Metal: Buffer di Comandi

Il rendering in Metal è organizzato attraverso code di comandi asincrone. Lo sviluppatore crea MTLCommandBuffer, codifica al suo interno comandi di rendering o calcolo e lo invia a MTLCommandQueue. La GPU esegue i comandi in sequenza mentre la CPU può continuare a lavorare. La sincronizzazione avviene tramite semafori o completionHandler.

MTLCommandQueue e MTLCommandBuffer

MTLCommandQueue — una coda di comandi creata da MTLDevice. Un'applicazione può avere più code per grafica, calcolo e copia. Ogni coda garantisce l'esecuzione sequenziale dei comandi. MTLCommandBuffer — un contenitore per un lotto di lavoro GPU. Dopo la codifica, viene inviato ed eseguito sulla GPU.

swift
// Ciclo di rendering principale
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()

Il metodo drawPrimitives esegue il rendering della geometria. Il parametro vertexCount specifica il numero di vertici. Un nuovo command buffer viene creato per ogni fotogramma. Present sincronizza il rendering con il VSync del display. Metal gestisce automaticamente la sincronizzazione con il display tramite CAMetalLayer.

Stato della Pipeline di Rendering

MTLRenderPipelineState — uno stato di pipeline di rendering compilato, che include vertex e fragment shader, configurazione depth-stencil, blending e formato dei pixel di output. Creare un pipeline state è un'operazione costosa, quindi gli oggetti vengono memorizzati nella cache e riutilizzati. Diversi pipeline state vengono creati per diverse combinazioni di shader.

Metal 3.1 ha introdotto il rendering veloce tramite Immutable Samplers che vengono memorizzati nella cache della GPU per accelerare il texture sampling. Metal supporta fino a 31 texture per slot shader su Apple Silicon. Sui dispositivi più vecchi con A13 e inferiori il limite è ridotto a 16 slot. Si consiglia di combinare le texture in Texture Atlases per ridurre il numero di campioni.

Metal Shading Language e Shader

Metal Shading Language (MSL) è un linguaggio di programmazione di shader basato su C++14 con estensioni per il calcolo GPU. MSL supporta template, overload di funzioni, namespace e aritmetica degli indirizzi. Gli shader vengono compilati in codice GPU binario tramite il backend LLVM di Apple.

Vertex e Fragment Shader

Vertex shader elabora ogni vertice: trasforma le coordinate dallo spazio mondo allo spazio schermo, calcola le normali e trasmette i dati al fragment shader. Fragment shader calcola il colore di ogni pixel: applica texture, illuminazione ed effetti di post-elaborazione.

cpp
// Vertex shader Metal
#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;
}

Gli attributi [[attribute(N)]] corrispondono ai formati dei vertici specificati in MTLVertexDescriptor. Il buffer [buffer(0)] passa la matrice MVP come variabile uniform. La posizione del vertice deve essere contrassegnata con [[position]] per essere passata al rasterizer. Tutti i tipi vettoriali MSL — float2, float3, float4 — vengono mappati sui registri hardware della GPU.

Compute Kernel

Compute shader (kernel) è una funzione GPU eseguita al di fuori della pipeline grafica. Le funzioni kernel sono contrassegnate dal qualificatore kernel e vengono eseguite in thread organizzati in threadgroup. I compute shader vengono utilizzati per elaborazione immagini, simulazione fisica, ML e post-elaborazione.

cpp
// Kernel di calcolo per sfocatura immagine
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);
}

Il parametro gid [[thread_position_in_grid]] contiene l'indice univoco del thread. Texture2D<type> è specializzato per tipo di pixel: half (FP16), float (FP32). I compute kernel possono essere avviati con una dimensione della griglia di oltre 1 miliardo di thread su M4 Ultra. La dimensione massima del threadgroup è di 1024 thread sulle GPU Apple Silicon.

Prestazioni e Metal Performance Shaders

Metal Performance Shaders (MPS) è una libreria di funzioni GPU ottimizzate fornita da Apple. MPS include reti neurali convoluzionali (MPSNNConvolution), moltiplicazione di matrici (MPSMatrixMultiplication), ordinamento (MPSParallelSort) ed elaborazione immagini (MPSImageGaussianBlur). Tutte le funzioni sono ottimizzate per GPU Apple specifiche.

MetalFX Upscaling

MetalFX è una tecnologia di upscaling e anti-aliasing, concorrente di NVIDIA DLSS e AMD FSR. MetalFX offre due modalità: Spatial (upscaling spaziale tramite algoritmo FSR 2) e Temporal (upscaling temporale con motion vector). MetalFX Temporal offre una qualità vicina al 4K nativo partendo da un rendering a 1440p.

Secondo Apple (2025), MetalFX Temporal su M4 Max offre fino a 3x di miglioramento delle prestazioni nei giochi mantenendo una qualità visivamente indistinguibile dalla risoluzione nativa. MetalFX funziona su qualsiasi GPU che supporti Metal 3, senza core tensor dedicati. L'integrazione di MetalFX in un progetto richiede circa 50 righe di codice.

Ray Tracing in Metal

Ray Tracing in Metal 3 è supportato sui chip M3, M4 e A17 Pro con unità di accelerazione hardware (Ray Tracing Accelerators). Metal fornisce MTLAccelerationStructure per la costruzione di BVH e MTLIntersectionFunction per l'intersezione dei raggi negli shader. Scene massicce con milioni di triangoli vengono compilate in BVH in millisecondi.

Secondo Apple (2025), il ray tracing hardware su M4 Ultra esegue fino a 40 miliardi di intersezioni di raggi al secondo (Giga rays/s). È 4 volte più veloce del ray tracing software su M1 Ultra. Metal RT supporta intersection query, geometria dinamica e Motion Blur per animazioni realistiche. Riflessi e ombre con ray tracing funzionano in tempo reale a 60 FPS.

Memoria Unificata e Zero-Copy

Unified Memory è l'architettura Apple Silicon dove CPU e GPU condividono la stessa memoria fisica. Metal su Apple Silicon non richiede la copia dei dati tra CPU e GPU: MTLBuffer in modalità shared è accessibile a entrambi i processori senza copia. Ciò elimina il principale collo di bottiglia delle GPU tradizionali (trasferimenti PCIe).

Zero-Copy in Metal permette alla CPU di scrivere dati in un buffer e alla GPU di leggerli senza ritardi. Secondo Apple (2025), ciò offre un miglioramento delle prestazioni del 30–50% rispetto alle GPU discrete in giochi e attività ML. Per GPU discrete (Mac Pro con Radeon) Metal supporta la modalità managed con sincronizzazione automatica tramite memory barrier.

Domande Frequenti

Cos'è Metal e a cosa serve?

Metal è l'API GPU a basso livello di Apple che fornisce un overhead minimo della CPU. Viene utilizzato per grafica 3D, calcolo ML, elaborazione immagini e simulazioni su iOS, macOS e tvOS. Sostituisce OpenGL e OpenCL.

In cosa Metal si differenzia da Vulkan?

Metal funziona solo su dispositivi Apple, integrato con Unified Memory e Metal Performance Shaders. Vulkan è un'API multipiattaforma per Windows, Android e Linux. Entrambe le API sono comparabili in termini di prestazioni, ma Metal ha un overhead inferiore su Apple Silicon.

Metal supporta il ray tracing?

Sì, con Metal 3 sui chip M3, M4 e A17 Pro è disponibile il ray tracing hardware. Metal fornisce MTLAccelerationStructure e supporto per intersection query negli shader. Prestazioni — fino a 40 Giga rays/s su M4 Ultra.

Cos'è MetalFX Upscaling?

MetalFX è la tecnologia di upscaling di Apple con modalità Spatial e Temporal. Funziona su qualsiasi GPU con Metal 3, senza core tensor. Offre fino a 3x di miglioramento delle prestazioni con qualità vicina al 4K nativo su M4 Max.

È difficile iniziare a lavorare con Metal?

La barriera d'ingresso è più alta di SceneKit o Unity a causa della gestione delle risorse a basso livello. Apple fornisce Metal Sample Code e tutorial su developer.apple.com. Il rendering base di un triangolo richiede circa 200 righe di codice.

Riepilogo

  • Metal — API GPU a basso livello di Apple con overhead CPU minimo
  • MTLDevice e MTLCommandQueue — le fondamenta dell'architettura con gestione esplicita delle risorse
  • MTLCommandBuffer e codificatori consentono la registrazione multithread dei comandi GPU
  • Metal Shading Language (C++14) supporta vertex, fragment, compute e mesh shader
  • MetalFX — upscaling con fino a 3x di miglioramento su qualsiasi GPU con Metal 3
  • Ray tracing hardware disponibile su M3/M4/A17 Pro
  • Memoria unificata su Apple Silicon elimina la copia dei dati tra CPU e GPU

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche