mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@@ -251,3 +251,106 @@ process-local. For cases registered with `coherent_as_flush` (Flywheel-style
|
|||||||
unflushed persistent maps, e.g. the Create fixtures), pass
|
unflushed persistent maps, e.g. the Create fixtures), pass
|
||||||
`--ez coherent_as_flush true` so the replay runs with
|
`--ez coherent_as_flush true` so the replay runs with
|
||||||
`MOBILEGL_COHERENT_AS_FLUSH=1`.
|
`MOBILEGL_COHERENT_AS_FLUSH=1`.
|
||||||
|
|
||||||
|
## Reproducing the Android DirectGLES lane on Linux (ANGLE on lavapipe)
|
||||||
|
|
||||||
|
The APK workflow's DirectGLES lane is not the same stack as the Linux one, which
|
||||||
|
is why a case can be green here and red there:
|
||||||
|
|
||||||
|
| lane | stack |
|
||||||
|
| --- | --- |
|
||||||
|
| Linux `Test` retrace, DirectGLES | Espryt -> Mesa GLES -> llvmpipe |
|
||||||
|
| Android `APK` retrace, DirectGLES | Espryt -> **ANGLE** -> Mesa Vulkan (lavapipe) |
|
||||||
|
| Android `APK` retrace, DirectVulkan | Magma -> lavapipe (no ANGLE) |
|
||||||
|
|
||||||
|
Only the Android DirectGLES lane puts ANGLE in the middle, so an ANGLE
|
||||||
|
translation difference shows up in exactly one of the six combinations. That
|
||||||
|
stack can be reproduced on Linux without an emulator, which is far faster to
|
||||||
|
iterate on than a CI round trip. The Android emulator SDK ships a glibc ANGLE:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ANGLE=$ANDROID_SDK_ROOT/emulator/lib64/gles_angle
|
||||||
|
mkdir -p ~/angle-farm && cd ~/angle-farm
|
||||||
|
# MobileGL dlopens these two names; ANGLE's own libEGL then dlopens the
|
||||||
|
# unsuffixed libGLESv2.so from the same directory - without that symlink it
|
||||||
|
# loads a truncated entry-point table and dies on a missing EGL function.
|
||||||
|
ln -sf $ANGLE/libEGL.so libEGL_angle.so
|
||||||
|
ln -sf $ANGLE/libGLESv2.so libGLESv2_angle.so
|
||||||
|
ln -sf $ANGLE/libEGL.so libEGL.so
|
||||||
|
ln -sf $ANGLE/libGLESv2.so libGLESv2.so
|
||||||
|
ln -sf $ANGLE/libvulkan.so.1 libvulkan.so.1 # else eglInitialize fails
|
||||||
|
|
||||||
|
MOBILEGL_USE_ANGLE=1 \
|
||||||
|
LD_LIBRARY_PATH=~/angle-farm:/path/to/build/ \
|
||||||
|
VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.json \
|
||||||
|
ANGLE_DEFAULT_PLATFORM=vulkan \
|
||||||
|
./mobilegl_trace_replay --trace trace.trace --golden golden.png \
|
||||||
|
--target-call N --width 854 --height 480 --backend DirectGLES \
|
||||||
|
--output outdir --pbuffer-surface
|
||||||
|
```
|
||||||
|
|
||||||
|
`ANGLE_DEFAULT_PLATFORM=vulkan` is required: ANGLE otherwise picks its OpenGL
|
||||||
|
backend and you get `ANGLE (Mesa, llvmpipe ..., OpenGL 4.6 (Core Profile))`
|
||||||
|
instead of the CI-shaped `ANGLE (Mesa, Vulkan 1.x (llvmpipe ...))`. Check
|
||||||
|
`MOBILEGL_TRACE_GL_RENDERER` in `outdir/retrace.log` before trusting a result.
|
||||||
|
Run the binary directly rather than through `ctest`, whose `ENVIRONMENT`
|
||||||
|
property overrides these variables. Build with clang, not gcc: gcc rejects
|
||||||
|
`GLXImpl.cpp` under `-Wchanges-meaning`.
|
||||||
|
|
||||||
|
### improved-transparency-minecraft-26.3 on the ANGLE lane
|
||||||
|
|
||||||
|
This case has never passed on the Android DirectGLES lane. It renders correctly
|
||||||
|
everywhere else, including Android DirectVulkan on the same emulator. The
|
||||||
|
rendered frame loses the whole translucent layer - clouds and water are absent
|
||||||
|
while opaque geometry is pixel-exact - so the compositing chain never receives
|
||||||
|
the translucent content rather than blending it wrongly.
|
||||||
|
|
||||||
|
It is not a MobileGL defect. Replaying the fixture through the recipe above and
|
||||||
|
through Mesa GLES, with a `MOBILEGL_LOG_LEVEL_DEBUG` build, gives
|
||||||
|
SSIM 1.000000 on Mesa and 0.970127 on ANGLE while MobileGL issues a
|
||||||
|
**byte-identical GL call stream** - 2698222 calls, same names, same order, same
|
||||||
|
arguments, the only difference being how often the app polls
|
||||||
|
`glClientWaitSync`. Both drivers are asked for exactly the same thing and
|
||||||
|
disagree about the pixels, so the divergence is below MobileGL, in ANGLE's
|
||||||
|
GLES-to-Vulkan translation (or in something we emit that is legal but
|
||||||
|
underspecified and the two implementations resolve differently).
|
||||||
|
|
||||||
|
Do not "fix" this by editing the DirectGLES blend or draw-buffer paths. Two
|
||||||
|
candidates were tested and ruled out: per-attachment blend equations are both
|
||||||
|
recorded and applied correctly on ANGLE (`glBlendEquationSeparatei` with GL_MAX
|
||||||
|
on one attachment reads back as GL_MAX and rasterizes as GL_MAX), and the GLES
|
||||||
|
draw-buffer slot restriction is already handled by
|
||||||
|
`BackendFramebufferObject::RecomputeBackendColorSlots`. Narrowing this further
|
||||||
|
means bisecting inside the frame to find which GLES construct ANGLE mistranslates;
|
||||||
|
the accommodation, once known, belongs with the existing
|
||||||
|
`--avoid-angle-llvmpipe-*` flags rather than in shared backend code.
|
||||||
|
|
||||||
|
#### Where in the frame it goes wrong
|
||||||
|
|
||||||
|
Snapshotting the same intra-frame call points on both stacks (`--target-call`,
|
||||||
|
ten replays in parallel, logs to `/dev/null`) localises it. SSIM against the
|
||||||
|
golden at each point:
|
||||||
|
|
||||||
|
| target call | what runs there | Mesa | ANGLE | gap |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| 2667445 | last opaque draw, into FBO 29 | 0.146477 | 0.000195 | - |
|
||||||
|
| 2667488 | **OIT composite**: fullscreen triangle, program 50, into FBO 3 | 0.976448 | 0.945409 | 0.031 |
|
||||||
|
| 2667543 | post draw, program 56 | 0.985380 | 0.954480 | 0.031 |
|
||||||
|
| 2667595 | post draw, program 64 | 0.985685 | 0.954788 | 0.031 |
|
||||||
|
| 2667619 | golden point | 1.000000 | 0.970127 | 0.030 |
|
||||||
|
|
||||||
|
The gap opens at the composite and is then constant to four decimal places -
|
||||||
|
every pass after 2667488 contributes the same increment on both drivers. So
|
||||||
|
nothing downstream of the composite is implicated, and the GUI/post chain is
|
||||||
|
fine. The two stacks already disagree at 2667445, before the composite runs,
|
||||||
|
which points at the translucent accumulation targets the composite samples
|
||||||
|
rather than at the composite draw itself.
|
||||||
|
|
||||||
|
That is as far as this went. What is still unknown is **which** GLES construct
|
||||||
|
in the accumulation chain ANGLE translates differently - naming it needs the
|
||||||
|
intermediate FBO attachments dumped either side of 2667488 on both stacks,
|
||||||
|
which the replay CLI cannot currently do (it snapshots one framebuffer, not all
|
||||||
|
attachments). Until it is named there is nothing to put behind an
|
||||||
|
`--avoid-angle-llvmpipe-*` flag and nothing precise enough to file upstream, so
|
||||||
|
the fixture stays red on the Android DirectGLES lane rather than being papered
|
||||||
|
over.
|
||||||
|
|||||||
Reference in New Issue
Block a user