目次

Metal (iOS/tvOS/macOS)

対応 GPU の機能グループは 4 種類

iOS9 では新たに GPUFamily3 が追加されています。

Family Group Platform PVRTCv1/ETC2 ASTC DXT(BC) CubeArray TexSize Indirect Draw Tessellation GPU
iOS GPUFamily1 PowerVR Series 6 (Rogue) iOS Apple A7 Y N N N 8192 N N PowerVR G6430
iOS GPUFamily2 PowerVR Series 6XT iOS Apple A8/A8X Y Y N N 8192 N N PowerVR GX6450/GX6850
iOS GPUFamily3 PowerVR Series 7XT iOS Apple A9/A9X Y Y N N 16384 Y Y PowerVR GT7600/GT7(12)
OSX GPUFamily1 Desktop GPUs Mac OS X (macOS) N N Y Y 16384 Y Y GeForce/RADEON GCN/Intel HD Grahics

Metal は Mac OS X 10.11 El Capitan 以降で対応します。Metal に対応している GPU は下記の通り。

GPU ごとの違い

GPU Family D32F_S8 D24_S8 ThreadGroup
PowerVR G6430 iOS GPUFamily1 Y N 512/512
PowerVR GX6450/GX6850 iOS GPUFamily2 Y N 512/512
GeForce Kepler OSX GPUFamily1 Y Y 1024/1024
Intel HD Graphics OSX GPUFamily1 Y N 512/512

API Set

Metal の API は Objective-C です。 OpenGL とは違い C/C++ から直接呼び出すことはできません。

Metal Framework

MetalKit

iOS と OS X の違い

iOS 版 Metal はハードウエアが PowerVR Series 6/6XT/7XT のみなので、API 構造が PowerVR の仕様に従っています。 OS X 版も基本的に iOS 版を踏襲しているものの、 Intel HD Graphcis / GeForce / RADEON 等多くの GPU で動作させるためか、一部汎用的な仕様に改められています。

OS X 版の OpenGL 4.1 との違い

OS X 10.10 / iOS 9 / tvOS 9 まで

Mobile 向け API 、しかも特定の PowerVR 向けに設計された API なので若干仕様に偏りがあります。 想定 GPU が OpenGL ES 3.1 相当なので、ComputeShader はあるものの GeometryShader/Tessellator 等の OpenGL 4.x 相当の機能がありません。 OpenGL 4.x の完全な代わりとしては物足りない部分がいろいろ出てくる可能性があります。 iOS 向け Application の移植が当面の用途になるかもしれません。

macOS 10.11 / iOS 10 以降

macOS 10.11, iOS 10 以降で大幅な機能拡張が行われています。 macOS 及び iOS の A9/A9X (PowerVR GT7xxx) で Tessellator が導入されました。 Pipeline 構造は DirectX11/OpenGL4 とは異なるものの、同等の機能を実装できるようになっています。

Texture の転送

iOS では UMA 前提なので、他の低レベル API と違い Metal のリソース転送は即座に行われます。 OSX では Discrete GPU も存在するため DMA 転送が必要です。iOS の API との互換性を保つために、Default で Managed Resource が用いられます。 直接転送命令を意識せずに更新できるので、他の低レベル API よりも扱いが簡単になっています。 他の低レベル API の Copy に相当するのが Blt API です。これらを用いて自分でリソースを転送することもできます。

Thread 並列化

CommandBuffer の生成は Thread 並列化が可能です。CPU 負荷を大きく減らすことができます。

ただし CommandBuffer の生成には CommandEncoder が必要で、PowerVR の TBDR アーキテクチャに従い CommandEncoder は RenderTarget (FrameBuffer) と結びついています。 CommandEncoder は Thread 間で共有することができないため、同じ RenderTarget へ書き込む描画命令を複数の CommandBuffer に分けることができません。

この問題に対応するため、ParallelRenderCommandEncoder という専用の仕組みが用意されています。 ParallelRenderCommandEncoder は、スレッド毎に使用できる複数の RenderCommandEncoder を作成することができます。 これを用いると単一の CommandBuffer の生成を複数のスレッドに分解することができます。