From 2b8ba7d69c465a9dc96876c7d39035e64e0547f8 Mon Sep 17 00:00:00 2001 From: leaiss Date: Wed, 27 May 2026 14:42:14 -0700 Subject: [PATCH] docs: Android Vulkan extension survey for pre-Lume-Pad bring-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inventories every Vulkan device extension the runtime requests at xrCreateVulkanDeviceKHR on Android (from oxr_vulkan.c with the AHardwareBuffer + FD-sync platform flags). Cross-references each against: - what swiftshader/gfxstream provides on the emulator (observed via today's smoke runs) - what Adreno 6xx/7xx on Lume Pad is expected to provide (per vulkan.gpuinfo.org reports for Snapdragon 845/888) Predicts which xrCreate* call should advance past the emulator wall on real hardware vs which steps will be the first hardware-specific behavior. Includes a step-by-step expectation table for first Lume Pad bring-up, mapping each log line to the emulator/Lume Pad expected outcomes. Key prediction: extensions #6 (VK_ANDROID_external_memory_android_ hardware_buffer), #7 (VK_KHR_sampler_ycbcr_conversion), and #10 (VK_EXT_queue_family_foreign) are the three swiftshader doesn't provide — all AHardwareBuffer-related — and all three are standard on Adreno's Android Vulkan ICD. So Lume Pad should clear the emulator wall at first device creation. If the prediction is wrong, the doc's "How to update" section points at the exact code change to make. --- .../android-vulkan-extension-survey.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 docs/getting-started/android-vulkan-extension-survey.md diff --git a/docs/getting-started/android-vulkan-extension-survey.md b/docs/getting-started/android-vulkan-extension-survey.md new file mode 100644 index 000000000..1c969a72a --- /dev/null +++ b/docs/getting-started/android-vulkan-extension-survey.md @@ -0,0 +1,130 @@ +# Android Vulkan Extension Survey + +Pre-Lume-Pad reference. Lists every Vulkan device extension the runtime ++ test app request at session bring-up, and predicts what's present on +the emulator (swiftshader-via-gfxstream) vs Lume Pad's Adreno GPU. + +The point: when you plug in Lume Pad and run `scripts/android-smoketest.sh`, +**you should know in advance which `xrCreate*` step is expected to advance +past the emulator wall and which steps will be the first to touch +hardware-specific behavior**. If anything else fails, that's a bug worth +investigating. + +## Lume Pad 2 GPU baseline + +| | | +|---|---| +| SoC | Snapdragon 845 (Adreno 630, Lume Pad 1) or 888 (Adreno 660, Lume Pad 2) | +| Vulkan driver | Qualcomm Adreno Vulkan ICD (system, signed) | +| Vulkan API version | 1.1 minimum, 1.3 typical for Adreno 660+ | +| Source of truth | `vulkan.gpuinfo.org` reports for the exact device model | + +## Required device extensions (xrCreateVulkanDeviceKHR side) + +The runtime appends these to whatever the test app already requests. +Source: `src/xrt/state_trackers/oxr/oxr_vulkan.c::required_vk_device_extensions[]` +on Android (`XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER` + +`XRT_GRAPHICS_SYNC_HANDLE_IS_FD`). + +| # | Extension | Adreno 6xx/7xx | Emulator (swiftshader) | Notes | +|---|---|:---:|:---:|---| +| 1 | `VK_KHR_dedicated_allocation` | ✅ | ✅ | Core in 1.1 | +| 2 | `VK_KHR_external_fence` | ✅ | ✅ | Core in 1.1 | +| 3 | `VK_KHR_external_memory` | ✅ | ✅ | Core in 1.1 | +| 4 | `VK_KHR_external_semaphore` | ✅ | ✅ | Core in 1.1 | +| 5 | `VK_KHR_get_memory_requirements2` | ✅ | ✅ | Core in 1.1 | +| 6 | `VK_ANDROID_external_memory_android_hardware_buffer` | ✅ | ❌ | Android-only. **First likely emulator-wall** | +| 7 | `VK_KHR_sampler_ycbcr_conversion` | ✅ | ⚠️ | Required by #6; transitively missing on emulator | +| 8 | `VK_KHR_maintenance1` | ✅ | ✅ | Core in 1.1 | +| 9 | `VK_KHR_bind_memory2` | ✅ | ✅ | Core in 1.1 | +| 10 | `VK_EXT_queue_family_foreign` | ✅ | ❌ | Required by #6; tied to AHardwareBuffer | + +**Emulator failure mode (today, captured 2026-05-27):** at session bring-up, +`null_compositor_create_system_with_dims` calls `vk_create_device` and gets +`VK_ERROR_EXTENSION_NOT_PRESENT`. The runtime gracefully degrades and lets +`xrCreateInstance` succeed (sentinel fires). The test app's own +`xrCreateVulkanDeviceKHR` then fails with the same error a few calls later +once it tries to enable an extension swiftshader doesn't have. Both fails +are the same root cause: **extensions #6/#7/#10 are AHardwareBuffer-related +and swiftshader doesn't implement them.** + +**Lume Pad prediction:** all 10 required extensions present. Both +`null_compositor`'s VK device AND the test app's VK device should succeed. + +## Optional device extensions (silently skipped if missing) + +Source: `src/xrt/state_trackers/oxr/oxr_vulkan.c::optional_device_extensions[]` +on Android. + +| Extension | Adreno 6xx/7xx | Emulator | Notes | +|---|:---:|:---:|---| +| `VK_KHR_external_semaphore_fd` | ✅ | ✅ | Used for cross-process sync | +| `VK_KHR_external_fence_fd` | ✅ | ✅ | Used for cross-process sync | +| `VK_KHR_image_format_list` | ✅ | ✅ | Swapchain image format optimisation | +| `VK_KHR_timeline_semaphore` | ✅ | ⚠️ | Adreno added in 2020 drivers; older devices may miss | + +## Null compositor's separate VK device + +The runtime's null compositor builds its own VkDevice (the "internal" +device, separate from the app-facing one). Same list as above plus +`VK_KHR_swapchain` (line 90 of `null_compositor.c`). On Android the null +compositor doesn't need a present surface, so swapchain is harmless if +present but **its absence won't break headless operation** (only the +internal device init logs a WARN and the runtime falls through to the +fallback path). + +## CNSDK plug-in's VK requirements + +The CNSDK plug-in does NOT create its own VkDevice — it uses the device +the runtime hands it via the DP `create_dp_vk` factory. So all CNSDK VK +calls go through the test-app-created device, which already has the full +required-extension set above. + +CNSDK's `leia_interlacer_vulkan_initialize` will fail at runtime if the +device is missing any of the extensions CNSDK uses internally. The CNSDK +0.7.28 source isn't fully transparent on this; check the published +`vulkaninfo` for Adreno 6xx and confirm at first session if the +interlacer errors out. + +## Step-by-step expectation at first Lume Pad bring-up + +Walk through these in order — the column heading is what should appear +in logcat at each milestone. + +| Step | Log line | Emulator | Lume Pad expected | +|---|---|:---:|:---:| +| Loader init | `xrInitializeLoaderKHR -> XR_SUCCESS` | ✅ | ✅ | +| Broker resolves runtime | `OpenXR-Loader: Got runtime: package: …` | ✅ | ✅ | +| Plug-in dlopen | `plugin loader: active plug-in: id=leia-cnsdk …` | ✅ | ✅ | +| **Null compositor VK device** | `monado.create_device: VK_ERROR_EXTENSION_NOT_PRESENT` | ❌ (expected) | ✅ (no error log) | +| Instance creation | `ANDROID_POC_SENTINEL xrCreateInstance=XR_SUCCESS` | ✅ | ✅ | +| `xrGetSystem` | `System: "DisplayXR: Leia CNSDK (Android)"` | ✅ | ✅ | +| `xrGetVulkanGraphicsRequirements2KHR` | `Vulkan API: min=1.0.0 max=…` | ✅ | ✅ | +| `xrCreateVulkanInstanceKHR` | `xrCreateVulkanInstanceKHR -> XR_SUCCESS` | ✅ | ✅ | +| `xrGetVulkanGraphicsDevice2KHR` | `xrGetVulkanGraphicsDevice2KHR -> XR_SUCCESS` | ✅ | ✅ | +| **`xrCreateVulkanDeviceKHR`** | `xrCreateVulkanDeviceKHR -> XR_SUCCESS` (no `vk_result=-7`) | ❌ vk_result=-7 (expected) | ✅ first-touch hardware step | +| `xrCreateSession` | `xrBeginSession returned XR_SUCCESS` | (unreached) | ✅ | +| `leia_interlacer_vulkan_initialize` | DP creation log | (unreached) | ✅ if all CNSDK-needed exts present | +| First frame | `Atlas blit: view_count=2, hardware_3d=1` | (unreached) | ✅ | + +## What to grep for if Lume Pad fails + +```bash +# Which extension exactly is missing (Adreno driver will spell it out): +adb logcat | grep -i 'extension not found\|extension not supported\|VK_ERROR_EXTENSION_NOT_PRESENT' + +# What Adreno actually reports: +adb logcat | grep -i 'vulkan' | grep -i 'apiVersion\|driverName\|deviceName' + +# All Vulkan-related WARN+ERROR from the runtime: +adb logcat | grep -E 'monado\.(create_device|vk_|comp_)' | grep -E 'ERROR|WARN' +``` + +## How to update this doc + +If Lume Pad reveals an extension we got wrong here: + +1. Capture the exact error: `adb logcat | grep -A2 VK_ERROR_EXTENSION_NOT_PRESENT` +2. Look up the device's actual extension list at `vulkan.gpuinfo.org`. +3. Update the matching row's "Adreno" column with ❌ + a note on which Adreno gen lost support. +4. If the runtime needs to make the extension optional, change it in `src/xrt/state_trackers/oxr/oxr_vulkan.c` (move from `required_vk_device_extensions[]` to `optional_device_extensions[]`).