Metalのデバッグに関連する機能やツールの使い方を本記事にまとめていこうと思います。

GPUフレームキャプチャ

XcodeにビルトインされているMetalのデバッグ機能。

Metal利用アプリを実行中、カメラ型のアイコン("Capture GPU Frame")を押すと、その瞬間のGPUフレームがキャプチャされ、次のような画面になる。

Screen Shot 2018-01-20 at 16.14.56.png

非常に高機能なので、詳細はそれぞれの項にて。

ラベル

Metalのクラスやプロトコルは文字列型のlabelというプロパティを備えているものが多くある。

例:

  • MTLCommandQueue
  • MTLResource
    • MTLBuffer, MTLTexture
  • MTLFunction
  • MTLRenderPipelineDescriptor
  • MTLCommandBuffer
  • MTLCommandEncoder

たとえば次のようにラベルをつけておいて、

commandQueue.label = "HogeCommandQueue"
texture.label = "HogeTexture"
vertexBuffer.label = "HogeVertexBuffer"
texCoordBuffer.label = "HogeTexCoordBuffer"
vertexFunction.label = "HogeVertexFunction"
fragmentFunction.label = "HogeFragmentFunction"
descriptor.label = "HogeRenderPipeline"
commandBuffer.label = "HogeCommandBuffer"
renderEncoder.label = "HogeRenderCommandEncoder"

XcodeでGPUフレームをキャプチャすると、ナビゲータ内でのコマンドエンコーダやリソース名に、自分がつけたラベルが表示されるので、識別しやすくなる。

Screen Shot 2018-01-20 at 16.19.57.png

ラベルは Instruments で見た場合にもこんな感じで適用されている。

Screen Shot 2018-01-20 at 16.24.42.png

というわけでパスが複雑な処理を行う場合はラベルをつけておくとデバッグやパフォーマンスにおけるボトルネックの特定が捗る。

デバッググループ

MTLCommandEncoderはiOS 8から、MTLCommandBufferはiOS 11から以下のようなメソッドが使える。

public func pushDebugGroup(_ string: String)
public func popDebugGroup()

push〜popの間にそのコマンドエンコーダやコマンドバッファに対して行った処理が、XcodeでのGPUフレームキャプチャ画面におけるナビゲータ上にフォルダアイコンでまとめられて表示される。

renderEncoder.pushDebugGroup("HogeCommandEncoderDebugGroup")
renderEncoder.insertDebugSignpost("HogeDebugSignpost")

guard let renderPipeline = renderPipeline else {fatalError()}
renderEncoder.setRenderPipelineState(renderPipeline)
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderEncoder.setVertexBuffer(texCoordBuffer, offset: 0, index: 1)
renderEncoder.setFragmentTexture(texture, index: 0)
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4)
renderEncoder.endEncoding()

commandBuffer.present(drawable)
commandBuffer.commit()
commandBuffer.waitUntilCompleted()

commandBuffer.popDebugGroup()
renderEncoder.popDebugGroup()

Screen Shot 2018-01-20 at 16.40.19.png

insertDebugSignpost

MTLCommandEncoderのメソッド。

public func insertDebugSignpost(_ string: String)

公式リファレンスによると、

Inserts a string into the command buffer.

When debugging with Xcode, this string may appear.

ちょっと用途がよくわからない。。コマンドバッファへのエンコードがうまくいってるかを確認するため?

シェーダの処理毎のパフォーマンス確認

ナビゲータの右上の方にあるアイコンをクリックして「View Frame By Performance」を選択。(デフォルトは「View Frame By Call」)

リストからパフォーマンスを見たいシェーダを選択すると、ソース上に処理時間のパーセンテージが表示される。

Screen Shot 2018-01-20 at 16.47.38.png

(表示されないケースもあった。理由は分かり次第追記します)

Remarks

ナビゲータから"Pipeline Statistics"を選択すると、"Remarks"という欄に、warning的な事項が表示される。

Screen Shot 2018-01-20 at 16.52.25 copy.png

Instruments

(続く)

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.