marfrit 54fb20bcc0 iter1 phase 4: H7 confirmed by panfrost kernel source-read
Read Linux 6.12 panfrost source. Smoking gun chain:

(a) panfrost_gem.c:262 — obj->base.map_wc = !pfdev->coherent
    Imports get write-combine (uncached) CPU mapping if non-coherent.

(b) panfrost_drv.c:625 — pfdev->coherent comes from DT dma-coherent.
    On ohm: NO dma-coherent in /sys/firmware/devicetree/base/.
    So pfdev->coherent = false.

(c) panfrost_mmu.c:330 — int prot = IOMMU_READ | IOMMU_WRITE
    NO IOMMU_CACHE. Mali's IOMMU mapping is non-snooping.
    Mali reads directly from DRAM, bypassing CPU caches.

(d) KWin caches EGL_images per-fd (eglbackend.cpp:282).
    Cache sync only at dma_buf_map_attachment time (one-time).

(e) V4L2 doesn't attach dma_resv fences to CAPTURE buffers on DQBUF.
    No per-frame cache flush trigger.

Architectural picture: hantro writes through CPU L1/L2/L3 caches,
Mali reads through non-snooping IOMMU, sees stale/zero DRAM. Result:
green frames.

Counter-validation: --vo=gpu (CPU-mmap → glTexSubImage2D upload to
Mali-private BO) works correctly. CPU mmap triggers begin_cpu_access
sync. Mali-private BO is naturally cache-coherent. Per-frame implicit
sync via the CPU mmap path.

Why DMA_BUF_IOCTL_SYNC (phase 3) didn't help: that's CPU-side cache
management. Doesn't propagate to GPU IOMMU.

ROOT CAUSE: Same root cause as our upstream vb2_dma_resv RFC v2.
With V4L2 attaching dma_resv fence on DQBUF, mesa-panfrost's implicit
fence-wait at sample time enforces cache writeback. RFC v2 IS the fix.

Proposed iter2 path: build linux-pinetab2-danctnix-besser 7.0 with
RFC v2 patches applied, install on ohm, retest. ~2-3 hours total.

If green goes away, we have:
  - confirmation that our RFC fixes a shipping-product bug
  - a locally shippable kernel package
  - strong data point for the v2 cover letter

Posted to dmabuf-modifier-triage#1 comment 260.
2026-05-08 22:40:51 +00:00

dmabuf-modifier-triage

TL;DR

Focused triage campaign for marfrit/libva-multiplanar#1mpv --vo=dmabuf-wayland produces solid green frames on ohm regardless of decoder backend (--hwdec=vaapi, --hwdec=v4l2request). --vo=gpu displays correct content. The bug is squarely in the dmabuf-wayland↔KWin presentation handoff, not in the decoder.

This campaign exists because libva-multiplanar's iter9 was scoped narrowly to fix its own decoder-side cap_pool/REQBUFS cascade (marfrit/libva-v4l2-request-fourier#1) and shouldn't bloat to take on the presentation-layer bug. KWin/panfrost stack work is also explicitly out-of-scope for libva-multiplanar per its Out-of-scope README section.

Locked question

Identify the layer responsible for the dmabuf-wayland green on ohm — libva (vaExportSurfaceHandle modifier reporting), ffmpeg V4L2 request hwaccel (AVDRMFrameDescriptor modifier), KWin (linux-dmabuf-v1 accept logic), Mesa-panfrost (modifier import constraints), or the kernel hantro driver (buffer attribute reporting). File upstream where appropriate; fix what's locally in scope.

Performance / "make smooth" is explicitly out of this campaign — the goal is bisection-down to the offending layer + a recorded fix or upstream filing per layer. The user's working HW-decode workflow on ohm right now is --vo=gpu --hwdec=v4l2request (slow but correct), which is sufficient until this campaign lands.

Hardware target

  • ohm — PineTab2, Rockchip RK3566 (note: prior README references to RK3568 corrected per ~/src/libva-multiplanar/libva-v4l2-request-fourier/ commit dcaa1f1). hantro G1 decoder, Mali-G52 (Bifrost) GPU via panfrost.
  • KWin 6.x via Plasma 6 Wayland.
  • Reproducer: ~/fourier-test/bbb_1080p30_h264.mp4 (Pinebook Pro / ohm shared corpus from ohm_gl_fix campaign).

Other hosts may serve as A/B controls (different GPU + same decoder, or same GPU + different decoder) — see phase0_findings.md for the planned matrix.

Process

8(+1) phase loop per feedback_dev_process.md. Phase 0 = locked-question + substrate. Phase 5 review uses the sonnet-architect subagent pattern.

In-session-acquired data discipline per feedback_replicate_baseline_first.md: the libva-multiplanar campaign's decoder-side measurements are reference history, not threshold sources for this campaign's cells.

Predecessor work this campaign builds on

  • ../libva-multiplanar/ — closed iter1..iter5 + iter6/7/8 work on the libva-v4l2-request-fourier fork. The campaign's iter5/8 close claimed "mpv --hwdec=vaapi smooth" on ohm — that claim is what was found to fail on 2026-05-08, with the green being one of the two failure modes (the other is the libva cascade, separately tracked at iter9). Cross-link from libva-multiplanar README's "Known issues at iter8 production tip" section.
  • ../kwin-overlay-subsurface/ — closed without patch. phase2_source_findings.md covers PineTab2's rockchip-drm plane format/modifier table. Plane 39 (Primary, NV12 LINEAR) is the only NV12-capable scanout. Useful because the modifier negotiation we're triaging here may overlap with the scanout-plane-modifier facts that campaign captured.
  • ../x11-session-research/ — confirmed the scanout-plane gap isn't fixable by switching session servers. Also useful negative space: this triage shouldn't waste cycles on "switch off Wayland" experiments that the predecessor already ran.
  • ~/.claude/projects/-home-mfritsche-src-fourier/memory/project_libva_multiplanar_state.md — campaign-state memory captures the package shipped + both bugs found.

External reference:

Repository layout

~/src/dmabuf-modifier-triage/                  <- this campaign (its own git repo)
├── README.md                                  <- this file
├── phase0_findings.md                         <- locked question + Phase 0 work list
├── (worklist.md, phase[2-8]*.md as phases land)
└── (no fork code lives here — bug is presentation-side, not in libva-v4l2-request-fourier;
     fixes either land upstream or in kwin-fourier / panfrost-side packages)

The campaign repo stays separate from any fork. If a fix lands as a downstream patch, it lives in ~/src/marfrit-packages/arch/<package>/ (kwin-fourier, mesa, etc.) per the existing fourier umbrella convention, with a pointer back to this campaign's findings.

Operator-facing repo URL: git.reauktion.de/marfrit/dmabuf-modifier-triage — created empty during scaffolding, no push until first iteration finds something worth publishing.

Non-upstreaming default

Inherited from feedback_no_upstream.md. Exception: when triage proves the bug is upstream code (KWin / Mesa-panfrost / kernel), opening a properly-formatted upstream bug report is the only useful outcome of that line of investigation, so this campaign explicitly does plan upstream filings as deliverables when scope-correct. Upstream submissions land in ~/src/marfrit-packages/upstream-submissions/dmabuf-modifier-triage/ per the existing convention.

Build infrastructure

No build host needed — this is a triage campaign, not a code-bearing one. Reproductions run on ohm directly. If a kwin-fourier rebuild is required for an A/B test, the existing boltzmann + marfrit-publish path applies.

S
Description
dmabuf-wayland presentation handoff triage on ohm — sibling campaign to libva-multiplanar/fresnel-fourier
Readme 480 KiB
Languages
C 100%