LoginSignup
7
7

More than 3 years have passed since last update.

Android Vulkan(特にMali GPU) のデバッグメモ

Last updated at Posted at 2020-02-19

注意事項

Android Vulkan で不都合があると, デバッグや不都合解析に無限に時間が溶けてしまいます. 最近(2020/02)で Android 9 or later であれば, それなりに多くの confirmance tests をパスしているはずで, ドライバやライブラリは安定してきた感がありますが, まだまだリスクがあります.

まずは, GLES で済むのであれば GLES にしておきましょう.
(ちなみに, Android 9 or 10 では, GLES 2.0 は ANGLE を介して裏では Vulkan で動かしてくれるらしい?)

コードの構成

まず, なるべくコードを PC と同一にして, PC 上でデバッグしやすくしておきます.

https://github.com/SaschaWillems/Vulkan-glTF-PBR あたりを参考にするのがおすすめです.

Vulkan アプリのコードは, 基本 C++(NativeActivity)を想定します.

デバッグの方法

  • Vulkan validation layer を有効にする https://qiita.com/syoyo/items/2e6f9b999452ac6c041f
    • Vulkan API を呼び出すレイヤーでのチェック
  • Address sanitizer を on にして Android アプリビルドする
  • RenderDoc を使う https://renderdoc.org/ (基本 PC でデバッグ. Android も一応ある)
  • SwiftShader(PC)で動かす
    • ただ, シェーダ内での out-of-bounds エラーでは, シェーダ(SPIR-V)を LLVM JIT で動かしているためか, あまり有益な stack trace は出してくれない
  • (optional) 画面を出さない, offscreen レンダリングの仕組みにして, Termux で Vulkan コードのデバッグができるようにする(e.g. シェーダのテストとか, compute shader で physics とかやりたいなど)
  • (optional) https://github.com/google/gapid RenderDoc と似たようなデバッガー. ただ, シーンデータが複雑だとトレース取得のメモリが足りないのか, エラーになりあまり使い物になりませんでした(PC GPU のデバッグはなぜか動かない)

未検証

  • Android シミュレータ(SwiftShader で実行?)で動かしてみる

よくあるエラー(著者が経験したエラー)

Descriptor set あたりでリソース不足エラー

Pool で必要なリソース(Uniform buffer, shader storage buffer など, それぞれのリソースに対して)が確保されているか確認しましょう. この場合は, Mali だと Vulkan API が error をレポートしてくれました(Adreno では error 出なかった)

vkWaitForFences で VK_ERROR_DEVICE_LOST(-4)

vkWaitForFences を数回後読んだ後に VK_ERROR_DEVICE_LOST(-4) に遭遇したら, Uniform buffer or Shader storage buffer あたりの out-of-bounds アクセスを疑ったほうがいいでしょう.
(実際, 著者が経験したものでは, SSBO への out-of-bounds アクセスエラーが原因でした)

robustBufferAccess

out-of-bounds アクセスなどは, robustBufferAccess でとりあえず suppress することができます.

robustBufferAccess を有効にするには,

VkPhysicalDeviceFeatures.rubustBufferAccess に VK_TRUE を設定して,
VkDevieCreateInfo.pEnabledFeaturesVkPhysicalDeviceFeatures 構造体変数を設定し, vkCreateDevice します.

一応, 事前に vkGetPhysicalDeviceFeatures で, rubustBufferAccess が利用できるかチェックしておきましょう(少なくとも最新 Mali と Adreno では利用できました).

robustBufferAccess 有効ではエラーが出ないが, robustBufferAccess 無効にするとエラーが出る場合, out-of-bounds アクセス周りがおかしいと判定できます.

描画の乱れ

描画の乱れは心の乱れ.

頂点モーフすると glitch が出たりなど.

こう言う感じ.

フレーム間で動的にデータが変化するもの(e.g. Uniform buffer に skinning matrix, morph の weight)は, swapChain ごとに用意しないと描画が乱れます.
(現在描画中のコマンドに, CPU からデータ上書きすると, GPU で読んだときにデータが前のフレームと次に描画するフレームのデータが混在しておかしくなる. モバイル GPU のように CPU/GPU で共有メモリの場合に顕著に出る)

同期に関連する不都合は, validation layers などで検出できないので悩ましいですね.

Android 向けの個別対応

  • 画面の回転や, スリープなどからの復帰 => SwapChain などの作り直し(Vulkan-glTF-PBR にはサンプルコード無いので, 自前でコード書く必要あり)

SwiftShader で試す.

SwiftShader(CPU Vulkan 実装) を Debug ビルド or ASAN 有効にして実行すると, out-of-bounds アクセスでは seg fault してくれたりします. ただ, シェーダの実行は marl 経由でスレッド実行 and LLVM JIT あたりで実行しているためか, 有意義な stack trace を出してくれないので, 原因が分かりづらいです. シェーダ内で printf とかできるとうれしいところ.

Mali 向け

Mali は, 性能出すためか, 省電力化を行うためか, 仕様に忠実であり不都合が多い(不定な入力に対して undefined behavior が多い)感じがあります(Adreno と比較して).
特に, Andreno(や PC GPU)では, out-of-bounds はいい感じにエラーにならずに処理してくれますが, Mali では device lost エラーになります(これはこれで正しい振る舞いですが)

Vulkan API レベルでは, 少なくとも Android 10 + Mali だと, 仕様に忠実であるためか, Adreno より厳格にエラーレポートしてくれる気がします.

また, OS や端末などによっても挙動がことなったりしますので, 何種類かの実デバイスでテストするのが理想です(Vulkan アプリを複数実端末でバッチでテストできる仕組みほしい)

robustBufferAccess ですが, いくらかパフォーマンスは落ちる & シーン(シェーダ)によるですが, すごい劇的な性能低下にはならず, 10% くらい遅くなるかな? という感じでした.

未検証. arm mobile studio(Mali Graphics Debugger)

最近では Graphics Analyzer と名前が変わっています.

Mali Graphics Debugger, 以前は rooted or hikey みたいな dev board でないと使えなかった気がしますが, 最近は non-rooted(つまり普通に売っているスマホ)でも動くのですね.

問題が起きたときの駆け込み寺とか...

ネットを漁っても, Android + Vulkan はあんまり有益な情報がないことが多いです... :cry:

Tencent ncnn https://github.com/Tencent/ncnn は, 涙ぐましい努力のたまものか, Mali のバグ回避のコードがあって意外と有益です.

Twitter が意外といいかもです. Android Vulkan に詳しい人たちの目に止まれば, なにか解決策を得られるかもしれませんよ?

あとは,, Khronos の Slack に Vulkan channel があります. ただ, 基本 PC GPU 系の人たちが集まっているので, Android 向けにはあまり有益な情報を得られないかもしれません.

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7