Android デバイスの Vulkan 実装の要件と現状の統計について

流通している Android デバイスの Vulkan 実装の性能を知るにはいくつかの情報源があり,
また Google が規定する最低の要件や, 大多数の端末でサポートを期待できる機能が存在する.

# 📓 追記: Android 13 と Vulkan 1.3
Android はしばらく Vulkan 1.1 で止まっているが, 最近, Android 13 の [CDD](#android-compatibility-definition-document) で Vulkan 1.1 だった表記が Vulkan 1.3 に変更されたため,
以下のCDDの Vulkan バージョン要求のまとめに加筆した.

また, Android の Vulkan ローダの, Vulkan 1.3 の対応を行う[コミット](https://android.googlesource.com/platform/frameworks/native/+/628c41ac1d788cac4310bd62e52323de98b392c9)がマージされた模様.
もちろんこれは, 各ベンダのドライバが 1.3 の実装を行うことを可能にするに過ぎない.

# Vulkan Hardware Database
[Vulkan Hardware Database by Sascha Willems](https://vulkan.gpuinfo.org/listdevices.php?platform=android)

お馴染みの Sascha Willems 氏の運営するデータベース.
[Vulkan Hardware Capability Viewer アプリ](https://play.google.com/store/apps/details?id=de.saschawillems.vulkancapsviewer)で収集された情報がここにアップロードされる.
他のプラットフォームの Vulkan Hardware Capability Viewer については, [Download セクション](https://vulkan.gpuinfo.org/download.php)へ (iOS や Mac 版もある).

拡張や Vk\*Features の有無や Vk\*Properties の値などの統計を見ることができる.
e.g [Android での `maxDrawIndirectCount`](https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxDrawIndirectCount&platform=android)

### 注意点
参考にしにくいエントリも存在し, 統計に影響を与えることがある:
- 昔の成熟度の低い Vulkan 実装
- エミュレータなどを通してホスト側GPUの情報が出ているもの
- ソフトウェア実装(lavapipe や SwiftShader)
- [Nubia Mini 5G なのに Pixel 6 を名乗っているもの(Qualcomm になっている)](https://vulkan.gpuinfo.org/displayreport.php?id=15189)

:::note info
Android で言うと, 例えば Build Date が 2018年の Adreno のドライバなどで以降の新しいものと比べて著しく性能が低い場合などがある(features が少なく各 properties の値が低い, etc).
:::

# Distribution Dashboard
[Distribution dashboard  |  Android Developers](https://developer.android.com/about/dashboards) には, アクティブなデバイスについて,
画面のサイズや実装される Vulkan や OpenGL ES のバージョンのほか,
[後述する Android Baseline profile](#android-baseline-2021-profile) への対応状況の統計が提供されている.

どうやらよく更新されているようで, 執筆時点では `active devices during a 7-day period ending on June 24, 2022` としている.

:::note info
Android Baseline 2021 profile に対応しているデバイスが執筆時点で 69.2% もあるのは, 以前の想定よりは期待の持てる状況に思える.
`shaderImageGatherExtended` を求めなければ 85.0% (!)
:::

# Android Baseline 2021 profile
Vulkan 1.3 と同時に発表された Vulkan Profiles の一環として, [Android Baseline 2021 profile](https://developer.android.com/ndk/guides/graphics/android-baseline-profile) がアナウンスされた.

Khronos Vulkan Roadmap 2022 profile などを含め, いくつかの profile が定義されているが,
Android Baseline 2021 profile は, 現在主に使用されているうち大多数の Android 端末の Vulkan 実装が, コア仕様の最低限の規定とは別にサポートする拡張やテクスチャフォーマット, 機能/性能などを定義した profile になる.

上記のとおり, 現在使用されているデバイスでのカバー率は執筆辞典で 約70% になり, 手加減すれば 約85% になる.

## 観察できる点
機能についていくつか観察できる点を挙げる. 機能については, 執筆時点での Vulkan Hardware Database での Android 端末のサポート率を引用する:
- APIバージョン: 1.0.68
  - 1.1 ではなく, 当然 `VK_ANDROID_external_memory_android_hardware_buffer` (70%) もない. 
- 対応あり
  - ETC2, ASTC_LDR (100%, 98%)
  - UBO, SSBO, sampled image の配列の dynamic indexing (98%, 85%, 98%)
  - fragmentStoresAndAtomics (97%)
- 対応なし
  - ジオメトリシェーダ (64%)
  - テレセーションシェーダ (65%)
  - multi draw indirect (66%)
  - vertexPipelineStoresAndAtomics (56%)
  - timestampComputeAndGraphics (81%)
    - Mali や PowerVR の多くが対応していないのが効いたか🤔?

拡張については, `VK_EXT_swapchain_colorspace` を要求するが `VK_EXT_hdr_metadata` は要求しない.

# Android Compatibility Definition Document
AOSP(Android Open Source Project) の [Android Compatibility Definition Document(Android 互換性定義ドキュメント)](https://source.android.com/compatibility/cdd?hl=ja) には, Android のバージョンごとに, デバイスが満足する必要のある要件が規定されており, その中にはデバイスの Vulkan 実装に対する要求も含まれる.

つまり, Vulkan 実装の機能/性能について, 最低限の要件を Google が規定したものになる.

## Vulkan: Android Baseline 2021 profile
Android 13 では, Vulkan 実装が Android Baseline 2021 profile の要求を満たすことを `STRONGLY RECOMMENDED` としている.

## グラフィクスAPIのサポート要求

Android 7.0~13 について, Compatibility Definition Document の _7.1.4. 2D and 3D Graphics Acceleration_ に規定される, グラフィクスAPIのサポートの要求をまとめる.

| API        | Android 7.0~7.1 | Android 8.0~8.1      | Android 9            | Android 10~12        | Android 13           |
| ---------- | --------------- | -------------------- | -------------------- | -------------------- | -------------------- |
| GLES 2.0   | MUST            | MUST                 | MUST                 | MUST                 | MUST                 |
| GLES 3.0   | SHOULD          | STRONGLY RECOMMENDED |                      |                      |                      |
| GLES 3.1   | SHOULD          | SHOULD               | STRONGLY RECOMMENDED | STRONGLY RECOMMENDED | STRONGLY RECOMMENDED |
| GLES 3.2   | SHOULD          | SHOULD               | SHOULD               | SHOULD               | SHOULD               |
| Vulkan 1.0 |                 | SHOULD,<br>STRONGLY RECOMMENDED<br>(with GLES 3.0 or 3.1) | SHOULD,<br>STRONGLY RECOMMENDED<br>(with GLES 3.1) | |  |
| Vulkan 1.1 |                 |                                                           |  | SHOULD,<br>STRONGLY RECOMMENDED<br>(with GLES 3.1) |  |
| Vulkan 1.3 |                 |                                                           |  | | STRONGLY RECOMMENDED |

## Vulkan の拡張のサポート要求
Compatibility Definition Document の _7.1.4.2 Vulkan_ に規定される, Vulkan の拡張のサポートの要求をまとめる.

_Virtual Reality Mode - High Performance_ の場合については除く; その場合, 要求はより厳しくなる.

Vulkan 1.0 をサポートする場合:
| 拡張                                                            | Android 7.0~7.1 | Android 8.0~8.1 | Android 9 | Android 10~12       | Android 13           | 
| --------------------------------------------------------------- | --------------- | --------------  | -------- | -------------------- | -------------------- |
| `VK_KHR_surface`, `VK_KHR_android_surface`, `VK_KHR_swapchain`  | MUST            | MUST            | MUST     | MUST                 | MUST                 |
| `VK_KHR_maintenance1`, `VK_KHR_get_physical_device_properties2` |                 | MUST            | MUST     | MUST                 | MUST                 |
| `VK_KHR_incremental_present`                                    |                 |                 | MUST     | MUST                 | MUST                 |
| `VK_KHR_driver_properties`, `VK_GOOGLE_display_timing`          |                 |                 |          | STRONGLY RECOMMENDED | STRONGLY RECOMMENDED |
| `VK_EXT_global_priority`                                        |                 |                 |          |                      | STRONGLY RECOMMENDED |

Vulkan 1.1 をサポートする場合:
| 拡張 | Android 7.0~8.1 | Android 9 | Android 10~12  |
| ---- | --------------- | --------- | ------------- |
| `SYNC_FD` external semaphore and handle types | | MUST | MUST |
| `VK_ANDROID_external_memory_android_hardware_buffer` | | STRONGLY_RECOMMENDED | MUST |

## HDR
Compatibility Definition Document の _2.2.1. Hardware_.

Android 9~12 では, [`Configuration.isScreenHdr()`](https://developer.android.com/reference/android/content/res/Configuration.html?hl=ja#isScreenHdr()) を通してHDRのサポートをアドバタイズする場合, 以下の拡張をサポートする必要がある:
- [`VK_EXT_swapchain_colorspace`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_swapchain_colorspace.html)
- [`VK_EXT_hdr_metadata`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_hdr_metadata.html)

`VK_EXT_swapchain_colorspace` で追加される列挙値の表すカラースペースのうち, Android では `VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT`, `VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT` がサポートされている[^android_vulkan_wide_color_gamut].
[^android_vulkan_wide_color_gamut]: [Enhance graphics with wide color content  |  Android Developers](https://developer.android.com/training/wide-color-gamut#vulkan)

:::note info
Qualcomm の True HDR に関する記事には, これら拡張についてのほか, HDRや広色域一般についてもよくまとまっている:
[Qualcomm True HDR — Game Developer Guides documentation](https://docs.qualcomm.com/bundle/publicresource/topics/80-78185-2/overview.html#qualcomm-true-hdr)
:::

# Vulkan 実装とその性能を示す \<uses-feature\>
以下が存在する:
- `android.hardware.vulkan.version`
- `android.hardware.vulkan.level`
- `android.hardware.vulkan.compute`

### Vulkan Hardware Version
| uses-feature                       | PackageManager 定数                |
| ---------------------------------- | --------------------------------- |
|[`android.hardware.vulkan.version`] | [FEATURE_VULKAN_HARDWARE_VERSION] |

[`android.hardware.vulkan.version`]: https://developer.android.com/guide/topics/manifest/uses-feature-element?hl=ja#vulkan-hw-features
[FEATURE_VULKAN_HARDWARE_VERSION]: https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_VERSION

存在は, ソフトウェア実装ではない Vulkan サポートの十分条件.
値は, サポートされている Vulkan のAPIバージョン [`VkPhysicalDeviceProperties::apiVersion`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceProperties.html) の値を示す.
エンコーディングは Vulkan の仕様で規定されるそれに従うが, variant バージョンがない模様 ?
➡️ Android 13 の CDD で, variant の値がゼロでなければならない(`MUST`)とする規定が追加された.
仕様書の [40.2.1. Version Numbers](https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#extendingvulkan-coreversions-versionnumbers) や, [`VK_MAKE_API_VERSION`の定義](https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_MAKE_API_VERSION.html)を参照のこと.

この値が `1.1.0` 以降ならば更に, 他のグラフィクスAPIやカメラなどとの interop を行うための機能がサポートされる:
- 拡張 [`VK_ANDROID_external_memory_android_hardware_buffer`](https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_ANDROID_external_memory_android_hardware_buffer.html)
- `SYNC_FD` external semaphore and fence handles 関連の拡張
- [`VkPhysicalDeviceSamplerYcbcrConversionFeatures::samplerYcbcrConversion`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceSamplerYcbcrConversionFeatures.html)

:::note warn
ただこれは[上記](#vulkan-の拡張のサポート要求)のとおり, Android 10 以降の場合のようである.
:::

### Vulkan Hardware Level
| uses-feature                     | PackageManager 定数              |
| -------------------------------- | ------------------------------- |
|[`android.hardware.vulkan.level`] | [FEATURE_VULKAN_HARDWARE_LEVEL] |

[`android.hardware.vulkan.level`]: https://developer.android.com/guide/topics/manifest/uses-feature-element?hl=ja#vulkan-hw-features
[FEATURE_VULKAN_HARDWARE_LEVEL]: https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_LEVEL

存在は, ソフトウェア実装ではない Vulkan サポートの十分条件.
値は, 最低限の [`VkPhysicalDeviceFeatures`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceFeatures.html) のサポート状況を示す:

| `android.hardware.vulkan.level` | VkPhysicalDeviceFeatures |
| ------------------------------- | ------------------------ |
| 0 | `textureCompressionETC2` |
| 1 | +<br>`fullDrawIndexUint32`<br>`imageCubeArray`<br>`independentBlend`<br>`geometryShader`<br>`tessellationShader`<br>`sampleRateShading`<br>`textureCompressionASTC_LDR`<br>`fragmentStoresAndAtomics`<br>`shaderImageGatherExtended`<br>`shaderUniformBufferArrayDynamicIndexing`<br>`shaderSampledImageArrayDynamicIndexing`

### Vulkan Hardware Compute
| uses-feature                     | PackageManager 定数              |
| -------------------------------- | ------------------------------- |
|[`android.hardware.vulkan.compute`] | [FEATURE_VULKAN_HARDWARE_COMPUTE] |

[`android.hardware.vulkan.compute`]: https://developer.android.com/guide/topics/manifest/uses-feature-element?hl=ja#vulkan-hw-features
[FEATURE_VULKAN_HARDWARE_COMPUTE]: https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_COMPUTE

存在は, ソフトウェア実装ではない Vulkan サポートの十分条件.
値は, Vulkan 1.0 のコア仕様の規定とは別にサポートされる, コンピュートシェーダ関連の機能を示す:

値 `0` は:
- variable pointer のサポート
  - 拡張 [`VK_KHR_variable_pointers`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_variable_pointers.html)
  - `VkPhysicalDeviceVariablePointerFeaturesKHR::variablePointers`
- `VkPhysicalDeviceLimits::maxPerStageDescriptorStorageBuffers` >= 16
  i.e コンピュートシェーダ中で使えるSSBOの数の最大数が16以上