Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The *Vulkan Profiles Tools* is a collection of tools delivered with the [Vulkan
* **[Vulkan Profiles Tools Overview](./OVERVIEW.md)**: Discover the components and how they work together.
* **[Change Log](./CHANGELOG.md)**: The history of *Vulkan Profiles Toolset* releases.
* **[Contributing](./CONTRIBUTING.md)**: How to contribute to the *Vulkan Profiles* repository.
* **[Vulkan Profiles Checker for Android](./android/profiles-checker/README.md)**: A sample Android app that reports the GPU/driver details and which *Vulkan Profiles* a device supports, including the exact unmet requirements.
* **[Bug reports](https://github.com/KhronosGroup/Vulkan-Profiles)**: Open a GitHub issue when you encounter a bug.

--------------
Expand Down
10 changes: 10 additions & 0 deletions android/profiles-checker/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Gradle / Android Studio
.gradle/
build/
.cxx/
local.properties
*.iml
.idea/
.kotlin/
captures/
.externalNativeBuild/
98 changes: 98 additions & 0 deletions android/profiles-checker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<!-- markdownlint-disable MD041 -->
<p align="left">Copyright 2026 Google LLC</p>

# Vulkan Profiles Checker (Android)

A small, dependency-light Android app that reports which *Vulkan Profiles* the device's driver supports and, for every unsupported profile, **exactly which requirements are not met** (missing extensions, disabled features, insufficient limits, unsupported format features, API version).

It also shows the GPU name, vendor/device IDs, the Vulkan API version, the raw and decoded driver version, and (when available) `VkPhysicalDeviceDriverProperties` (driver name, driver info, driver ID, conformance version), plus the Android system/SoC/driver-package properties.

## How it works

The app is a pure C++ `NativeActivity` (no Java/Kotlin code) built on top of the
[Vulkan Profiles API library](../../library/TUTORIAL.md) generated by this repository.

- At build time, CMake runs the repository's `scripts/vkprofiles.py` to generate a
**debug** header-only profiles library for the selected profiles. The debug
variant reports every unmet condition through `VP_DEBUG_MESSAGE_CALLBACK`.
- The app overrides that callback, captures the messages while calling
`vpGetInstanceProfileSupport` / `vpGetPhysicalDeviceProfileVariantsSupport`,
and groups them by *API version / Extensions / Features / Properties & limits / Formats*.
- The result is drawn with a tiny software renderer (system Roboto via `stb_truetype`)
and also written to logcat and to the app's private `report.txt`.

Profiles included by default (see `VP_CHECKER_PROFILES` in [CMakeLists.txt](app/src/main/cpp/CMakeLists.txt)):

| Profile | Source |
|---|---|
| `VP_ANDROID_15_requirements`, `VP_ANDROID_16_requirements`, `VP_ANDROID_17_requirements`, `VP_ANDROID_18_requirements` | `profiles/Android/` |
| `VP_ANDROID_vulkan_profile_2021`, `VP_ANDROID_vulkan_profile_2022`, `VP_ANDROID_vulkan_profile_2025` | `profiles/Android/` |
| `VP_KHR_roadmap_2022`, `VP_KHR_roadmap_2024`, `VP_KHR_roadmap_2026` | Vulkan-Headers `registry/profiles/VP_KHR_roadmap.json` |

## Requirements

- Android SDK with platform 35 and the NDK (the version bundled with your AGP is fine)
- CMake 3.22.1 (installed through the SDK manager)
- JDK 17 or newer
- Python 3.10 or newer on `PATH` (used to run `vkprofiles.py`; `jsonschema`/`pyparsing` are installed into a private venv automatically)
- Network access during the first configure (Vulkan-Headers and `stb_truetype.h` are fetched and pinned)

## Build

```sh
cd android/profiles-checker
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
```

Or open `android/profiles-checker` in Android Studio.

> The app must be built from inside the Vulkan-Profiles checkout: the native build
> locates `scripts/vkprofiles.py` and `profiles/Android/*.json` relative to itself.

### Useful CMake options

Pass them via `android.defaultConfig.externalNativeBuild.cmake.arguments` in
`app/build.gradle.kts` or the Android Studio CMake settings:

| Option | Purpose |
|---|---|
| `-DVP_CHECKER_PROFILES=...` | Comma separated list of profiles to compile in |
| `-DVULKAN_HEADERS_GIT_TAG=v1.4.364` | Vulkan-Headers tag used for headers / `vk.xml` |
| `-DVULKAN_PROFILES_PREBUILT_HEADER=/path/to/vulkan_profiles.hpp` | Skip Python/generation and use an existing **debug** header |

## Reading the results

Each profile row shows **SUPPORTED** or **NOT SUPPORTED (N unmet)**. Tap a row to expand it:

- **Failing capability blocks** – the capability blocks of the profile that did not validate.
- **Unmet instance requirements** – API version / instance extension problems.
- **Unmet device requirements** – grouped item-level conditions reported by the profiles library, e.g.
- `Extensions`: `VK_KHR_shader_float_controls`
- `Features`: `VkPhysicalDeviceVulkan12Features::shaderInt8 == VK_TRUE`
- `Properties & limits`: `VkPhysicalDeviceProperties2::properties.limits.maxImageDimension2D >= 8192`
- `Formats`: `VK_FORMAT_R16_UNORM: VkFormatProperties2::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)`

> For profiles with multiple variants, the list covers every variant the library
> evaluated; a profile is unsupported only when *no* variant validates.

The same content is available without the UI:

```sh
adb logcat -s VulkanProfilesChecker
adb shell run-as org.khronos.vulkanprofiles.checker cat files/report.txt
```

## Layout

```
android/profiles-checker/
├── app/src/main/AndroidManifest.xml NativeActivity, hasCode="false"
├── app/src/main/cpp/CMakeLists.txt FetchContent + header generation + native library
├── app/src/main/cpp/profile_checker.* Drives the profiles library, captures debug messages
├── app/src/main/cpp/device_info.* GPU / driver / system properties
├── app/src/main/cpp/report.* Plain text report (logcat + report.txt)
├── app/src/main/cpp/text_renderer.* stb_truetype software text rendering
├── app/src/main/cpp/ui.* Scrollable report view with tap-to-expand
└── app/src/main/cpp/main.cpp android_main / event loop
```
49 changes: 49 additions & 0 deletions android/profiles-checker/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
plugins {
id("com.android.application")
}

android {
namespace = "org.khronos.vulkanprofiles.checker"
compileSdk = 35
ndkVersion = "27.0.12077973"

defaultConfig {
applicationId = "org.khronos.vulkanprofiles.checker"
minSdk = 26
// targetSdk 35+ enforces edge-to-edge and the system bar insets are only
// exposed through Java WindowInsets APIs, which a code-less NativeActivity
// cannot use. Targeting 34 keeps the window laid out between the bars.
targetSdk = 34
versionCode = 1
versionName = "1.0"

ndk {
// arm64 for real devices, x86_64 for the emulator.
abiFilters += listOf("arm64-v8a", "x86_64")
}

externalNativeBuild {
cmake {
arguments += listOf(
"-DANDROID_STL=c++_static",
"-DANDROID_CPP_FEATURES=exceptions"
)
}
}
}

externalNativeBuild {
cmake {
path = file("src/main/cpp/CMakeLists.txt")
version = "3.22.1"
}
}

buildTypes {
release {
isMinifyEnabled = false
// Debug-signed so the release APK can still be side-loaded for testing.
signingConfig = signingConfigs.getByName("debug")
}
}
}
29 changes: 29 additions & 0 deletions android/profiles-checker/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<!-- No permissions are required: the app only queries the local Vulkan driver
and writes its report to the app's private files directory. -->

<uses-feature android:name="android.hardware.vulkan.version" android:required="false" />

<application
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:hasCode="false"
android:allowBackup="false"
android:theme="@style/AppTheme">

<activity
android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:exported="true"
android:launchMode="singleTop"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|uiMode|density|smallestScreenSize">
<meta-data android:name="android.app.lib_name" android:value="profiles_checker" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Loading
Loading