この記事は、Metal Advent Calendar2016の6日目の記事です。
以前にMetalのGPUコンピューティングについて解説記事を書きました。
[iOS] MetalでGPUコンピューティング (1)
[iOS] MetalでGPUコンピューティング (2)
本記事からは、何回かに分けてAppleが提供するGPUコンピューティングのサンプルコードの解説をしたいと思います。
Appleが提供するMetalのサンプルコードにMetalGameOfLifeというものがあります。
MetalGameOfLife
いわゆるライフゲームのアプリですが、Metalの並列プログラミングについての良いデモとなっています。
今後このサンプルコードをベースに、Metalの並列プログラミングの解説を行います。
このサンプルコードは、主に以下のファイルで構成されています。
AAPLRender.h
AAPLRender.m
AAPLViewController.h
AAPLViewController.m
Sharder.metal
このうち、AAPLRender.mには並列コンピューティング及び描画のCPU側のロジックが、Shader.metalには頂点シェーダー、フラグメントシェーダー、GPUコンピューティング用のシェーダーが書かれています。
まず、MTLDeviceについて解説を行います。
MTLDeviceは単一のGPUのインターフェイスです。
MTLDeviceなどのMetal関連の機能の多くはクラスではなくプロトコルなのですが、Metalが動作するデバイス毎にオブジェクトの型が異なるので、実装よりもインターフェイスを重視したためと思われます。
(参考)objc.io
サンプルコードではプロトコルを実装したオブジェクトの生成をAAPLViewController.mで行なっています。
MTKViewがMTLDeviceを実装したオブジェクトをプロパティとして持つ必要があるからです。
@property (nonatomic, weak) MTKView *metalView;
...
self.metalView = (MTKView *)self.view;
...
self.metalView.device = MTLCreateSystemDefaultDevice();
AAPLRender側ではこれをViewごと受け取り、weakなプロパティに入れておきます。
@property (nonatomic, weak) id<MTLDevice> device;
...
_device = _view.device;
この_deviceを用いて、以下のプロトコルを実装したオブジェクトが生成されます。
- MTLLibrary
- MTLCommandQueue
- MTLBuffer
- MTLRenderPipelineState
- MTLTexture
- MTLComputePipelineState
- MTLSamplerState
このように、MTLDeviceは様々なMetal関連のオブジェクトの生成に用いるとても重要なプロトコルなのです。
ちなみに、GPUの名前はMTLDeviseのnameプロパティで取得することができます。
NSLog(@"Devise name: %@", self.metalView.device.name);
例えばiPhone6 Plusの場合、上記はApple A8 GPUと出力されます。
今回はライフゲームのサンプルコード内におけるMTLDeviceの解説を行いました。
次回以降、サンプルコードの他の箇所についての解説を行なっていきます。