iter1 phase 2: hypothesis 2 ruled out by KWin source-read

Shallow-cloned KWin 6.6.4 (references/kwin-6.6.4/, gitignored) and
read the wl_dmabuf protocol handler + EGL import paths.

Findings:

(a) LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_add stores
    fd[i]/offset[i]/pitch[i] per plane index, no fd dedup, no
    cross-plane comparison.

(b) LinuxDmaBufParamsV1::test() does lseek(SEEK_END) per plane and
    range-checks against the result. Our exported size 3,657,728
    satisfies all checks for offset[1]=2,088,960 + pitch[1]=1920.

(c) EglDisplay::importDmaBufAsImage (egldisplay.cpp:166 combined
    and :218 per-plane) passes user-supplied fd/offset/pitch
    straight to eglCreateImage(EGL_LINUX_DMA_BUF_EXT) verbatim. No
    transformation.

(d) EglBackend::testImportBuffer (eglbackend.cpp:338) chooses
    between combined (line 342) and per-plane (line 353-356)
    based on whether NV12+LINEAR is in nonExternalOnlySupportedDrmFormats.
    Either path passes offset=2088960 to the driver.

KWin is innocent. Live hypothesis narrows to H1 (panfrost's
EGL_DMA_BUF_PLANE*_OFFSET_EXT handling for LINEAR NV12, most likely
via the per-plane RG88-from-offset-2088960 import path).

Posted to dmabuf-modifier-triage#1 comment 256.

Three of five hypotheses ruled out (H2, H3, H5). Remaining: H1
(panfrost EGL offset), H4 (kwin-fourier residual, low conf).
Next probe: minimal EGL importer harness on ohm.
This commit is contained in:
2026-05-08 21:43:28 +00:00
parent 89a4b81654
commit 735f7f7ae3
+8 -5
View File
@@ -75,7 +75,7 @@ So the green frame is **not caused by mpv or ffmpeg's descriptor construction**.
1. **Mali-G52 panfrost EGL_EXT_image_dma_buf_import_modifiers regression for NV12 with non-zero plane offset.** The driver may sample plane 1 from offset 0 of the imported fd instead of offset 2088960, giving zero-fill UV. Testable: a minimal EGL importer C program that imports a known NV12 dmabuf with offsets and reads back via `glReadPixels`. 1. **Mali-G52 panfrost EGL_EXT_image_dma_buf_import_modifiers regression for NV12 with non-zero plane offset.** The driver may sample plane 1 from offset 0 of the imported fd instead of offset 2088960, giving zero-fill UV. Testable: a minimal EGL importer C program that imports a known NV12 dmabuf with offsets and reads back via `glReadPixels`.
2. **KWin's wl_dmabuf import logic deduplicates the dup'd fds incorrectly.** If KWin sees two fds and detects (via `dma_buf_id` or kcmp(2)) that they're the same backing object, but then mishandles the per-plane offsets, this'd produce green. Testable: read KWin source `src/wayland/linuxdmabufv1clientbuffer.cpp` and compositor backend's EGL import path. 2. ~~**KWin's wl_dmabuf import logic deduplicates the dup'd fds incorrectly.**~~ **RULED OUT 2026-05-08** by source-read of KWin 6.6.4 at `references/kwin-6.6.4/src/wayland/linuxdmabufv1clientbuffer.cpp` + `src/opengl/{eglbackend,egldisplay}.cpp`. (a) `LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_add` simply stores per-plane fd/offset/pitch in separate slots, no dedup. (b) `LinuxDmaBufParamsV1::test()` does `lseek(SEEK_END)` per plane + range checks against the resulting size; our 3,657,728 satisfies all of them. (c) `EglDisplay::importDmaBufAsImage` (both the combined and per-plane forms) passes `dmabuf.fd[i]`, `dmabuf.offset[i]`, `dmabuf.pitch[i]` straight to `eglCreateImage(EGL_LINUX_DMA_BUF_EXT, ...)` with no transformation. (d) `EglBackend::testImportBuffer` chooses between combined import and per-plane (Y as R8 / UV as RG88 from offset 2,088,960) based on whether NV12+LINEAR is in `nonExternalOnlySupportedDrmFormats()`. **Either path** forwards `offset = 2,088,960` to the driver. KWin is innocent.
3. ~~**hantro kernel driver exports a `dma_buf` with `size` < full allocation.**~~ **RULED OUT 2026-05-08** by `/tmp/expbuf_probe.c` on ohm. Driver `hantro-vpu` on `rk3568-vpu-dec` reports `CAPTURE: NV12 1920x1088 num_planes=1 sizeimage=3655712`; `VIDIOC_EXPBUF` yields fd whose `lseek(fd, 0, SEEK_END) = 3,657,728` (page-rounded up from 3,655,712). Offset 2,088,960 (plane 1 base) is firmly inside the exported size. Kernel is innocent. 3. ~~**hantro kernel driver exports a `dma_buf` with `size` < full allocation.**~~ **RULED OUT 2026-05-08** by `/tmp/expbuf_probe.c` on ohm. Driver `hantro-vpu` on `rk3568-vpu-dec` reports `CAPTURE: NV12 1920x1088 num_planes=1 sizeimage=3655712`; `VIDIOC_EXPBUF` yields fd whose `lseek(fd, 0, SEEK_END) = 3,657,728` (page-rounded up from 3,655,712). Offset 2,088,960 (plane 1 base) is firmly inside the exported size. Kernel is innocent.
@@ -95,7 +95,10 @@ d. **Update `marfrit/dmabuf-modifier-triage#1`** with this revised analysis. The
## Status ## Status
- iter1 phase 2 closed 2026-05-08. Hypotheses 3 (hantro size cap) and ad-hoc 5 (offset-mismatch from sizeimage surprise) both ruled out via `/tmp/expbuf_probe.c` runtime measurement on ohm. Real layer narrowed to hypothesis 1 (panfrost EGL_dma_buf_import for non-zero offset) and hypothesis 2 (KWin wl_dmabuf import). Hypothesis 4 still latent. - iter1 phase 2 closed 2026-05-08. Three of five hypotheses ruled out:
- Acceptance criterion (`screenshots/frame10_expected.png`) is unchanged. - H2 (KWin wl_dmabuf import) — KWin 6.6.4 source-read clean; both wl-protocol params validation and EGL import paths forward user-supplied offset verbatim to `eglCreateImage`. Innocent.
- Delivery vehicle (`mpv-fourier-1:0.41.0-8`) is still the right shipping path **if** the fix turns out to be a defensive workaround in mpv. With kernel + ffmpeg + mpv all exonerated by source-read + runtime probe, the most likely landing layers are now Mesa-panfrost (`vulkan-panfrost` package — already in marfrit) or KWin (`kwin-fourier` package — already in marfrit). - H3 (hantro size cap) — `/tmp/expbuf_probe.c` runtime probe on ohm: `lseek(SEEK_END)=3,657,728`, well past offset 2,088,960. Innocent.
- Next probe: hypothesis 2 source-read of KWin (cheaper, ~30 min, no hardware) before hypothesis 1 EGL importer harness (~1-2h C code). - H5 (offset mismatch with hantro NV12 stride) — arithmetic disproves: Y at [0, 2,088,960), UV at [2,088,960, 3,133,440), trailing Rockchip metadata at [3,133,440, 3,655,712). ffmpeg's plane[1].offset is correct.
- **Live hypothesis: H1 — panfrost's `EGL_DMA_BUF_PLANE*_OFFSET_EXT` handling for LINEAR NV12 (or per-plane RG88 with non-zero offset).** Acceptance criterion (`screenshots/frame10_expected.png`) is unchanged.
- Delivery vehicle (`mpv-fourier-1:0.41.0-8`) is still the right shipping path **if** the fix turns out to be a defensive workaround in mpv. With kernel + ffmpeg + mpv + KWin all exonerated, the patch most likely lands in Mesa-panfrost (`vulkan-panfrost` package — already in marfrit). Less-likely fallback: kernel hantro driver-side adjustment.
- Next probe: a minimal EGL importer harness that recreates the per-plane RG88-from-offset-2088960 import. Run with a known-good NV12 buffer (synthesized in CPU memory, written to a CMA dmabuf via udmabuf) and `glReadPixels` the resulting EGL_image. If the read shows zeros where UV data should be, panfrost is confirmed culprit. ~1-2h C code, runs on ohm.