今回の結果の git コミット
fork した RenderDoc のリポジトリにコミットを追加してある.
後述の手順でビルドを行うと, VEL の *.so
がパッケージングされた org.renderdoc.renderdoccmd.arm64.apk
が生成される.
この APK を下記の手順で RenderDoc が使用するようにすると, VEL を使った RenderDoc キャプチャのリプレイが可能になる.
更新履歴
日付 | 内容 |
---|---|
2024-02-20 | 追記: APK の外部に存在する layer としての使用について |
導入
Vulkan Extension Layer (VEL)
Android に限らず Vulkan アプリで, ドライバがネイティブで対応していない拡張を用いるために,
polyfill layer である Vulkan Extension Layer (VEL) を用いることができる.
これらはドライバのアップデートをあまり期待できない Android において特に重宝し,
中でも VK_KHR_synchronization2
や VK_KHR_timeline_semaphore
のものを使いたい場合が多い.
VEL と RenderDoc キャプチャ
ただし Android でこれら VEL を用いるアプリを RenderDoc でデバッグしたいとき,
キャプチャを取るまでは問題ないが, 実際にそのキャプチャをリプレイ(i.e 開く)する際には,
デバイスが該当の拡張に対応していない旨のエラーが表示され, 続行することができない.
☝️ Adreno 650 のドライバ 512.444.0
がネイティブで VK_KHR_synchronization2
に対応していないため, キャプチャをリプレイすることができない.
クロスプラットフォームな Vulkan アプリを開発する際,
VK_KHR_synchronization2
や VK_KHR_timeline_semaphore
は是非使用したいところだが,
その際ドライバの新しくない Android 端末にも対応する場合にはこれら VEL を使うことが必須になる.
ただしそのときこれら端末では, RenderDoc によるGPUデバッグが行えないことになる.
今回はこの問題を解決したい.
Android における RenderDoc キャプチャのリプレイ
Android での RenderDoc キャプチャを開く際, 実際に行われるのは,
シリアライズされたグラフィクスAPIのコマンド列を Android 端末上の RenderDoc のアプリに送信して,
端末でそれらグラフィクスAPIのコマンド列を再実行(リプレイ)させることである.
この Android 端末上でのリプレイに用いられるアプリが,
org.renderdoc.renderdoccmd.arm64
や org.renderdoc.renderdoccmd.arm32
であり,
初回に Remote Context に接続した際に端末にインストールされる, お馴染みの画面のアプリになる.
☝️ org.renderdoc.renderdoccmd.arm64
アプリ
org.renderdoc.renderdoccmd.arm64
と VEL
リプレイ時に, キャプチャされたグラフィクスAPIのコマンド列を実行しているのは実機上の org.renderdoc.renderdoccmd.arm64
なので,
VEL の *.so
を利用できる必要があるのは当然, このアプリということになる.
つまり, 自分のアプリで VEL を使用するときにように, VEL の *.so
を renderdoccmd
の APK の lib/arm64-v8a
にパッケージング12してしまうのが手っ取り早い:
lib/arm64-v8a/libVkLayer_khronos_synchronization2.so
lib/arm64-v8a/libVkLayer_khronos_timeline_semaphore.so
まずは基本的な renderdoccmd
の Android 向けのビルドの手順を確認してから,
VEL の *.so
のこの APK へのパッケージングができるようにしていく.
APK の外部に存在する layer としての使用について
*.so
に対して org.renderdoc.renderdoccmd.arm64
で run-as
を使用する方法3だが,
これはうまくいかない.
run-as
した *.so
を認識させるには adb shell setprop debug.vulkan.layers
など設定を行う必要があるが,
これらの設定を, RenderDoc は Android 端末の Remote Context の確立時に, 消去してしまう:
Android::adbExecCommand(deviceID, "shell setprop debug.vulkan.layers :", ".", true);
Android::adbExecCommand(deviceID, "shell settings delete global enable_gpu_debug_layers", ".",
true);
Android::adbExecCommand(deviceID, "shell settings delete global gpu_debug_app", ".", true);
Android::adbExecCommand(deviceID, "shell settings delete global gpu_debug_layer_app", ".", true);
Android::adbExecCommand(deviceID, "shell settings delete global gpu_debug_layers", ".", true);
Android::adbExecCommand(deviceID, "shell settings delete global gpu_debug_layers_gles", ".", true);
Android 向けの renderdoccmd
のビルドと使用
Windows で行いたかったが, 公式ドキュメントの推奨に従って, 今回は WSL 上の Ubuntu で行う.
Android の開発環境の用意
Android SDK, Android NDK, Java Development Kit をインストールする.
公式ドキュメントの該当部分に従う.
Android 向けのビルド
公式ドキュメントの該当部分に従っていく.
Ninja
をインストール:
sudo apt update
sudo apt-get -y install ninja-build
クローンした RenderDoc のディレクトリへ移動:
cd renderdoc
ビルド:
mkdir build-android
cd build-android
cmake -DBUILD_ANDROID=On -DANDROID_ABI=arm64-v8a -G "Ninja" ..
ninja -j 8
ncurses5
が足りないようなことを言われたらインストール:
sudo apt-get -y install libncurses5
org.renderdoc.renderdoccmd.arm64.apk
が, renderdoc/build-android/bin
に生成されているはず.
使用
既に古い org.renderdoc.renderdoccmd.arm64
が Android 端末に入っている場合, アンインストールしておく:
adb uninstall org.renderdoc.renderdoccmd.arm64
RenderDoc のインストールディレクトリの plugins/android
に,
標準の org.renderdoc.renderdoccmd.arm64
が存在するので, 新しいものをこれに上書きする.
これで, Remote Context 接続の際にインストールされるリプレイ用アプリが, 今回ビルドしたものになる.
renderdoccmd
に VEL の *.so
がパッケージングされるようにする
renderdoc/renderdoccmd/android
に, ABI ごとのディレクトリに *.so
を入れたフォルダ vel
を用意する:
renderdoccmd/
├── 3rdparty/
├── android/
│ ├── AndroidManifest.xml
│ ├── Loader.java
│ ├── icon.png
│ ├── vel/ 👈🆕
│ │ ├── arm64-v8a/
│ │ │ ├── libVkLayer_khronos_synchronization2.so
│ │ │ └── libVkLayer_khronos_timeline_semaphore.so
│ │ └── armeabi-v7a/
│ │ ├── libVkLayer_khronos_synchronization2.so
│ │ └── libVkLayer_khronos_timeline_semaphore.so
│ └── wrap.sh
├── apple/
├── ...
renderdoc/renderdoccmd/CMakeLists.txt
に, これら *.so
をパッケージングするための記述を追加する:
# Copy in android package files, replacing the package name with the architecture-specific package name
configure_file(android/Loader.java ${CMAKE_CURRENT_BINARY_DIR}/src/org/renderdoc/renderdoccmd/Loader.java)
configure_file(android/AndroidManifest.xml ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml)
configure_file(android/icon.png ${CMAKE_CURRENT_BINARY_DIR}/res/drawable/icon.png COPYONLY)
+ configure_file(android/vel/${ANDROID_ABI}/libVkLayer_khronos_synchronization2.so ${CMAKE_CURRENT_BINARY_DIR}/vel/${ANDROID_ABI}/libVkLayer_khronos_synchronization2.so COPYONLY)
+ configure_file(android/vel/${ANDROID_ABI}/libVkLayer_khronos_timeline_semaphore.so ${CMAKE_CURRENT_BINARY_DIR}/vel/${ANDROID_ABI}/libVkLayer_khronos_timeline_semaphore.so COPYONLY)
add_custom_command(OUTPUT ${APK_FILE}
DEPENDS renderdoc
DEPENDS renderdoccmd
DEPENDS ${KEYSTORE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory libs/lib/${ANDROID_ABI}
COMMAND ${CMAKE_COMMAND} -E make_directory obj
COMMAND ${CMAKE_COMMAND} -E make_directory bin
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:renderdoc> libs/lib/${ANDROID_ABI}/$<TARGET_FILE_NAME:renderdoc>
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:renderdoccmd> libs/lib/${ANDROID_ABI}/$<TARGET_FILE_NAME:renderdoccmd>
+ COMMAND ${CMAKE_COMMAND} -E copy vel/${ANDROID_ABI}/libVkLayer_khronos_synchronization2.so libs/lib/${ANDROID_ABI}/libVkLayer_khronos_synchronization2.so
+ COMMAND ${CMAKE_COMMAND} -E copy vel/${ANDROID_ABI}/libVkLayer_khronos_timeline_semaphore.so libs/lib/${ANDROID_ABI}/libVkLayer_khronos_timeline_semaphore.so
)
この変更の上で上記の手順でビルドを行うと, *.so
がパッケージングされた APK が生成される.
org.renderdoc.renderdoccmd.arm64.apk/
├── AndroidManifest.xml
├── META-INF/
│ ├── MANIFEST.MF
│ ├── RDOCANDR.RSA
│ └── RDOCANDR.SF
├── classes.dex
├── lib/
│ └── arm64-v8a/
│ ├── libVkLayer_GLES_RenderDoc.so
│ ├── libVkLayer_khronos_synchronization2.so 👈🆕
│ ├── libVkLayer_khronos_timeline_semaphore.so 👈🆕
│ ├── librenderdoccmd.so
│ └── wrap.sh
├── res/
│ └── drawable/
│ └── icon.png
└── resources.arsc
この APK を上記の手順で RenderDoc が使用するようにすると, VEL を使った RenderDoc キャプチャのリプレイが可能になる.