I’ve seen a few developers struggling to get Vulkan validation layers working for Android applications, so here is quick recipe to do it with the fewest moving parts.

Method

There are a few different ways to install layer drivers on Android. When doing this by hand, and for developer tools, it is convenient to load layers without modifying the application APK. I therefore prefer to load layers from disk, because it has the fewest dependencies on other parts of the software stack.

As with most Android development, these instructions assume your device is in developer mode, visible to your desktop over adb, and your application is set to “debuggable” in its Android manifest.

The basic sequence of steps is:

  • Install your debuggable APK
  • Copy the layer library matching your application’s bitness to a host directory
  • Run the install script from the above directory
  • Do your development
  • Run the uninstall script to cleanup the layer installation
  • Uninstall your application

Note: The layer must be installed after the application, and uninstalled before the application, because the helper scripts use “run-as” to get permission to copy files into the application’s file system partition.

The layers

The most important thing is to keep your layer drivers up to date. Use the latest Khronos validation layer binaries from GitHub, not the layer drivers in the Android NDK.

Why?

  • The layer drivers are under active development and the project actively adds new checks and fixes bugs.
  • The layer driver needs to understand the version of Vulkan and associated extensions implemented by the driver underneath it. Out-of-date layers which target an older API version/extension set than the underlying driver will often throw incorrect validation errors or just crash.

So stay up to date with the upstream Khronos layers and save yourself a lot of headaches. You can find them here:

The scripts

The scripts below are Bash scripts, but are trivial enough to translate into other shell syntax as needed.

Install script

APP=com.your.app.here
LAYER_LIB=libVkLayer_khronos_validation.so
LAYER_NAME=VK_LAYER_KHRONOS_validation

adb push $LAYER_LIB /data/local/tmp
adb shell run-as $APP cp /data/local/tmp/$LAYER_LIB .
adb shell settings put global enable_gpu_debug_layers 1
adb shell settings put global gpu_debug_app $LAYER_APP
adb shell settings put global gpu_debug_layer_app $LAYER_APP
adb shell settings put global gpu_debug_layers $LAYER_NAME

Uninstall script

APP=com.your.app.here
LAYER_LIB=libVkLayer_khronos_validation.so
LAYER_NAME=VK_LAYER_KHRONOS_validation

adb shell rm /data/local/tmp/$LAYER_LIB
adb shell run-as $APP rm $LAYER_LIB
adb shell settings delete global enable_gpu_debug_layers
adb shell settings delete global gpu_debug_app
adb shell settings delete global gpu_debug_layers
adb shell settings delete global gpu_debug_layer_app

The important parts of this script are the clearing of the settings. This is sufficient to disable layers in the Android loader.

I prefer to leave no trace of teh tooling, and remove the layer library too. The layer will get removed when you uninstall the application, as it’s installed in the application directory, so you can remove the adb shell run-as $APP rm $LAYER_LIB step if you want to make this script application agnostic.

Footnotes

Android is intolerant of missing layer drivers. If you leave debug layers enabled in the Android settings but delete the layer library you will get a hard-exit when trying to start the application. If this happens just run the uninstall script (or at least the part which clears the settings) and try again.

Updates

  • 20 Apr ‘22: Added a note on importance of using the Khronos layers.