mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 05:38:31 +09:00
[Test] (CTS): run VK-GL-CTS KHR-GL33 against MobileGL on Android via a standalone glcts binary
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# Running the OpenGL CTS (VK-GL-CTS / KHR-GL33) against MobileGL on Android
|
||||
|
||||
Goal: measure how much of the OpenGL 3.3 core-profile conformance suite MobileGL
|
||||
passes, separately for each backend (`DirectGLES`, `DirectVulkan`).
|
||||
|
||||
## How MobileGL is reached from a test binary
|
||||
|
||||
MobileGL ships its own EGL implementation alongside its desktop-GL implementation
|
||||
in a single `libMobileGL.so`. A plain arm64 ELF in `/data/local/tmp` can therefore
|
||||
drive it with no APK and no Activity:
|
||||
|
||||
1. `setenv("MOBILEGL_BACKEND_TYPE", "DirectGLES"|"DirectVulkan")` **before** the
|
||||
library is mapped — MobileGL parses its configuration from an ELF constructor.
|
||||
2. `dlopen("libMobileGL.so")`, then `dlsym` the `egl*` and `gl*` entry points.
|
||||
MobileGL exports 45 EGL symbols and the desktop GL functions directly;
|
||||
`eglGetProcAddress` resolves the same set.
|
||||
3. `eglBindAPI(EGL_OPENGL_API)`, choose a config with `EGL_RENDERABLE_TYPE =
|
||||
EGL_OPENGL_BIT`, then `eglCreateContext` with
|
||||
`EGL_CONTEXT_OPENGL_PROFILE_MASK = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT` and
|
||||
major/minor `3`/`3`.
|
||||
|
||||
This yields a genuine GL 3.3 core context (`GL_CONTEXT_PROFILE_MASK == 0x1`).
|
||||
|
||||
## Surface type, per backend
|
||||
|
||||
| backend | pbuffer (headless) | window |
|
||||
|---|---|---|
|
||||
| `DirectGLES` | works | works |
|
||||
| `DirectVulkan` | **unusable** | works |
|
||||
|
||||
`DirectVulkan`'s pbuffer path builds a headless `VkSurfaceKHR` and so requires the
|
||||
`VK_EXT_headless_surface` instance extension, which Adreno's Android driver does
|
||||
not expose. It fails inside `eglMakeCurrent`, not at surface creation.
|
||||
|
||||
The workaround that keeps everything in a shell process: obtain a real
|
||||
`ANativeWindow` from **`AImageReader`** (`AImageReader_newWithUsage` +
|
||||
`AImageReader_getWindow`). It is an ordinary BufferQueue producer, so
|
||||
`vkCreateAndroidSurfaceKHR` accepts it, and no Activity is involved. Register an
|
||||
`onImageAvailable` listener that acquires and deletes each image — otherwise the
|
||||
producer blocks once `maxImages` buffers are in flight and the next swap hangs.
|
||||
|
||||
## Why the suite must render into an FBO
|
||||
|
||||
On a window surface, `DirectVulkan`'s `glReadPixels` from the **default
|
||||
framebuffer** returns all zeros, with no GL error, both before and after
|
||||
`eglSwapBuffers`. `DirectGLES` on the identical window is correct, and readback
|
||||
from a **user FBO is correct on both backends**.
|
||||
|
||||
Verified on two SoCs and two drivers, so this is MobileGL's behaviour rather than
|
||||
a driver quirk:
|
||||
|
||||
| device | GPU | driver | default-FB | user FBO |
|
||||
|---|---|---|---|---|
|
||||
| Xiaomi 24129PN74C | Adreno 830 | Vulkan 1.3.284 / 512.800.46 | zeros | ok |
|
||||
| Lenovo TB321FU | Adreno 750 | Vulkan 1.3.128 / 512.762.28 | zeros | ok |
|
||||
|
||||
dEQP verifies nearly every case through `glReadPixels`, so running it against the
|
||||
default framebuffer would score `DirectVulkan` near zero for a reason unrelated to
|
||||
conformance. The runs therefore use `--deqp-surface-type=fbo`, uniformly for both
|
||||
backends so the two numbers stay comparable.
|
||||
|
||||
## Other constraints the harness must respect
|
||||
|
||||
- `eglMakeCurrent` requires **draw == read** and rejects `EGL_NO_SURFACE` with
|
||||
`EGL_BAD_MATCH`. dEQP's `surfaceless` platform is therefore unusable, which is
|
||||
why this port supplies its own `tcu::Platform`.
|
||||
- MobileGL aborts during static teardown (`FORTIFY: pthread_mutex_lock called on a
|
||||
destroyed mutex`) *after* all work completes. Flush and `_exit()` so the exit
|
||||
code and the `.qpa` log survive.
|
||||
|
||||
## Contents
|
||||
|
||||
probe/mgprobe.c preflight gate: one backend x one surface type, checks
|
||||
context version/profile and both readback paths
|
||||
scripts/qpa_report.py .qpa -> pass rate, status histogram, worst groups
|
||||
|
||||
### Preflight
|
||||
|
||||
aarch64-linux-android26-clang -O1 -o mgprobe mgprobe.c -ldl -llog -landroid -lmediandk
|
||||
adb push mgprobe libMobileGL.so /data/local/tmp/mgcts/
|
||||
adb shell 'cd /data/local/tmp/mgcts && LD_LIBRARY_PATH=. ./mgprobe \
|
||||
--backend DirectVulkan --surface imagereader --lib ./libMobileGL.so'
|
||||
|
||||
Exit status is 0 when a 3.3 core context came up and FBO readback is correct.
|
||||
Default-framebuffer readback is reported but deliberately does not gate.
|
||||
Reference in New Issue
Block a user