はじめに

Metal DebuggerはXcodeの一部として組み込まれているツールです。
Appの単一フレームのキャプチャやデバッグが行え、レンダリングパイプラインの詳細を探りAPIの問題点を見つけるのに役立つ機能が備わっています。

Xcode 12においてはMetal DebuggerにSummary Viewが追加となりました。
Xcode 12でMetal Debuggerがどのようになっているか見ていきたいと思います。

確認した環境

iOSをターゲットとしての確認を行っていきます。

Xcode : Version 12.0.1
iPhone : iPhone 11 pro (iOS 14.0.1)

使用するサンプル

今回はアップル公式サンプルの一つである「Reflections with Layer Section」を用いて内容を見ていきたいと思います。

● Reflections with Layer Section
https://developer.apple.com/documentation/metal/rendering_reflections_with_fewer_render_passes

フレームのキャプチャ

まず、Xcodeのスキームオプションで「GPU Frame Capture」が有効であるかを確認します。

今回はiOSとして確認していくため、スキームをDeferredLighting-iOSに合わせておきます。
その状態で「Edit Scheme…」から「GPU Frame Capture」の設定を確認する事ができます。

Runを実行するとDebug Areaのログに「GPU Frame Capture」が有効であるといった内容があり、デバッグバーにカメラのアイコンが表示されている状態になっているかと思います。
フレームのキャプチャを行いたいタイミングでそのカメラアイコンを選択する事で、キャプチャが完了します。

Debug Navigatorの内容

フレームのキャプチャを行う事でNavigator AreaにあるDebug Navigatorの内容が対応したものに変更されます。

上部のDebug Gaugesとなっている部分には「Summary」「Counters」「Memory」各ツールを選択するためのメニューが表示されています。

さらにその下の部分には選択した内容に合わせた「View Frame By Call」 と 「View Frame By Pipeline State」での内容が表示されています。
切り替えに関してはNavigator Area上部で行う事ができます。

「View Frame By Call」では実際の処理が呼び出された流れでの表示になります。
「View Frame By Pipeline State」ではPipeline毎に別れた内容としての表示となります。

Summary View

では実際の内容を見ていきましょう。
まずはXcode12で追加されたSummary Viewを見ていきます。

Summary Viewではフレームに関する情報であるエンコーダー、パフォーマンス値、メモリ使用量、問題点に対する洞察などが一目で確認できる作りとなっています。
また、さらに調べたい領域に特化したツールへの移動も行えるものとなっています。
上部には「Export」のボタンがあり、こちらで書き出した「.gputrace」ファイルからXcode上でキャプチャーされた状態を復元する事が可能になります。

Overview

キャプチャーされたフレームにおける処理内容の回数が表示されています。

ここで「Show Dependencies」のボタンからDependency Viewerの表示を行う事ができます。

Performance

レンダリングに要する時間と使用されている頂点数が表示されます。

「Show Counters」でGPU Countersの表示を行う事ができます。

Memory

フレームとしてメモリ上の占めている内容が表示されます。

「Show Memory」でMemory Viewerの表示を行う事ができます。

Insights

メモリ使用量、帯域幅、パフォーマンス、MetalのAPI使用量の改善策を提案するものです。

左側で選択した内容に対してい右側に問題の説明、解決方法のヒント、関連するドキュメントへのリンクなど必要なガイドが表示されます。

Dependency Viewer

Dependency ViewerではAppでエンコードされたGPUパスの全体像をグラフィカルに確認する事ができます。
Summary ViewのOverviewにあるボタンからやDebug Navigatorを「View Frame By Call」表示している場合にCommand Bufferの部分を選択した際などに表示がされます。

Command Bufferとして大きく区切られているのが見て取れます。
Command Buffer内のレンダリングに要する時間やDrawコールの数、含まれているRender Encodersの内容なども表示されています。

GPU Counters

フレーム内のどこにGPU時間が費やされているかがひと目で分かるようになっています。

各Encoder毎か各Draw Call毎かの表示の切り替えが行え、さらにそれらに合わせたグループ別の表示が行えます。
カーソルを合わせた場合にはその時点でのサムネイルも表示され、EncoderやDrawを選択する事でDebug Areaの連動する事からどこにボトルネックがあるのかが大変分かりやすくなっています。

Memory Viewer

Metalでのアプリのリソースとメモリ使用量について表示されます。
フィルタによる表示内容の切り替えも簡単に行えるようになっています。

Shader Profiler

続くShader Debuggerでも必要となりますが、Build Settingsの”Produce debugging information”を”Yes, include source code”に変更しておきましょう。
また、今回の私の環境ではiOS Deployment Targetを14.0としておかないと動かない状況でした。
試される際には環境に合わせた変更をしてください。

Shader Profilerではシェーダーの各行毎のパフォーマンスを確認できます。
Debug Navigatorの表示内容を「View Frame By Pipeline State」とした上で任意のシェーダーを選択するとEditor Areaが概要のソースコードを表示します。
ソースコードの右側に処理時間に対する割合が表示されます。
ここでソースコードを変更し「Reload Shaders」のアイコンを選択する事で即座にパフォーマンスの変更内容が確認できます。

Shader Debugger

Debug Shaderアイコンを選択するとその時点でEditor Areaの内容がRender Encodersのものであった場合、VertexとFragmentのビジュアル的に表示れた内容の小ウィンドウが開きます。

そこでVertexであれば頂点、Fragmentであればピクセルを選択した上で小ウィンドウ右下のDebugボタンを選択する事でShader Debuggerの表示が行えます。
また直接Geometry Viewerからも同様にDebugボタンからShader Debuggerを表示することも可能です。

Shader Debuggerではブレークポイントなしで全ての変数値が表示されています。
Vertexの場合、その頂点に関連する三角形の他頂点の変数値も詳細から表示できます。

最後に

Metal Debuggerの内容について簡単にですが一通り見てみました。
今回のXcodeにビルドインされているMetal DebuggerとInstrumentsのMetal System Traceと合わせる事でMetalでの開発がより楽しくなるのではないでしょうか?

参考

● Gain insights into your Metal app with Xcode 12 (WWDC20)
https://developer.apple.com/videos/play/wwdc2020/10605/

● Optimize Metal Apps and Games with GPU Counters (WWDC20)
https://developer.apple.com/videos/play/wwdc2020/10603/

● Harness Apple GPUs with Metal (WWDC20)
https://developer.apple.com/videos/play/wwdc2020/10602/

● Delivering Optimized Metal Apps and Games (WWDC19)
https://developer.apple.com/videos/play/wwdc2019/606

● Metal Shader Debugging and Profiling (WWDC18)
https://developer.apple.com/videos/play/wwdc2018/608/

● Optimizing Performance with the Shader Profiler
https://developer.apple.com/documentation/metal/shader_authoring/optimizing_performance_with_the_shader_profiler

● Developing and Debugging Metal Shaders
https://developer.apple.com/documentation/metal/shader_authoring/developing_and_debugging_metal_shaders

● Viewing Your Frame Graph Dependency
https://developer.apple.com/documentation/metal/frame_capture_debugging_tools/viewing_your_frame_graph