ea9a25d3b103bbb44f39b736fa268b93273e2cec
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c801465469 |
fix(packaging): every channel that ships punktfunk-gamescope now builds it
The docs already told users where to get it — the Bazzite sysext, an Arch package, a NixOS option — and none of the three were true. `rpm.yml` built the sysext without ever passing `--gamescope`, `arch.yml` did not know the PKGBUILD existed, and the nix derivation had never been evaluated once. Evaluating it found its central assumption wrong: `gamescope.unwrapped` does not exist on current nixpkgs, where `gamescope` IS the buildable derivation, so the override threw on every build. It now prefers `.unwrapped` where a future nixpkgs wraps it and checks the RESULT is patchable — `overrideAttrs` on a symlinkJoin succeeds and does nothing, which would install an UNPATCHED gamescope under a name the host reads as a promise of HDR. Both it and the PKGBUILD had also drifted to a stale patch list: two patches named where three exist, one of them under the level-1 filename retired when the cursor patch landed. Both read the patch directory now, so the list cannot go stale again. The PKGBUILD additionally delegates the whole build to `build-punktfunk-gamescope.sh` rather than re-deriving the meson invocation — its copy had already lost `force_fallback_for=wlroots`, and unlike Fedora 43, Arch ships wlroots, so that package would have linked it shared and shipped a binary that starts only on machines carrying the dev library. It asserts its own pinned rev matches the script's, the one thing makepkg needs statically. Both CI builds are cached on `packaging/gamescope/**`, which is the only reason this is affordable: that tree depends on nothing else in the repo, so a normal push restores a binary instead of spending ten minutes on someone else's C++. And both are best-effort. punktfunk works without this binary — SDR on the gamescope backend, which is what every release before this one did — so a hiccup building gamescope must not cost the packages those workflows exist to publish. A failure warns and is never cached, so the next run retries. `rpm.yml` also installs Fedora's own gamescope for its runtime libraries: the sysext verifies our binary by executing `--version`, and on a cache hit nothing else in the job would have pulled libavif/luajit/seatd in. Verified by evaluating and patch-phase-building the nix derivation against nixos-unstable: all three patches apply to nixpkgs' already-patched 3.16.25 tree, and the banner stamps +pfhdr2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
9eb9f74893 |
fix(gamescope): the patch did not compile on Fedora/Bazzite — three real defects
Built it for the first time, on the AMD Bazzite box (`.116`, RADV 780M, Fedora 43 toolbox). The patches applied cleanly to the pinned rev and the configure got all the way through wlroots — then found three things no amount of reading would have: **1. `SPA_VIDEO_TRANSFER_SMPTE2084` does not exist on Fedora 43.** PipeWire 1.4.11's transfer-function enum stops at `ADOBERGB`: SPA grew BT2020_10 / SMPTE2084 / ARIB_STD_B67 as one later block. So the patch simply did not compile on the distro it is primarily FOR. This is the same trap punktfunk's own consumer documents and works around — `pf-capture`'s `pw_pods.rs` spells the value out as `14` for exactly this reason — and the fix is the same: spell out both colorimetry values, because the enum is wire ABI mirroring GStreamer's, not a private detail. `SPA_VIDEO_COLOR_PRIMARIES_BT2020` is present here but gets the same treatment, since its own header comment says `\since 1.6` and there is no reason to depend on that. The `PW_CHECK_VERSION(1, 0, 0)` guard was also just wrong: it tests the library version, which says nothing about which enum members a header names. It now guards only the FORMAT constants, which are what it was actually right about. **2. The build pulled in three subprojects we never ship.** gamescope's own unit tests want Catch2 **v3** (`catch2-with-main`) and Fedora ships v2, so the configure died on a test suite that is not ours to build. Also disabled: the OpenVR integration (a code path a headless capture session never enters) and the WSI layer — which would have been WORSE than wasted work, since the distro gamescope package installs that same layer and ours would have collided with it file-for-file. **3. `dnf builddep gamescope` is not sufficient.** It resolves Fedora's *packaged* gamescope, which is older than the master we pin, and misses `xorg-x11-server-Xwayland-devel` — without which wlroots fails several minutes in with a `xserver.wrap` error that names nothing useful. Documented with the symptom, so the next person recognises it in one line instead of ten minutes. |
||
|
|
fd648aa776 |
feat(gamescope): put the cursor in the node, so a session can be zero-copy
gamescope keeps the pointer out of its PipeWire node — it lives on a hardware plane for scanout, and `paint_pipewire()` composites a separate, reduced frame that never includes it. So punktfunk has always reconstructed it from XFixes and blended it in host-side. That blend is what has been blocking the zero-CSC encode path, and the cost is larger than it sounds: `VulkanVideoEncoder::open` refuses the RGB-direct (EFC) source for any session with `cursor_blend`, because that front end is fixed-function and has no blend stage. `cursor_blend_for` sets it unconditionally for gamescope. Net effect: a gamescope session paid a full-frame colour-conversion pass per frame, forever, for a pointer. So put the cursor where it belongs. A second carried gamescope patch adds `--pipewire-composite-cursor` (off by default — the node has never carried it, and a consumer that draws its own would get two), painting it with the same `MouseCursor::paint` call the scanout composite uses. It scales for free: paint_pipewire has already set `currentOutputWidth/Height` to the capture size, which is what that function scales against. The repaint test grows the cursor's state beside the commit ids — a pointer-only move produces no commit, so without it the composited cursor would freeze on a static screen while the real one moved, and a cursor that became hidden would never be erased. Host side, the `+pfhdr` marker becomes a monotonic PATCH LEVEL, so one probe answers every capability the session must know before it is planned (level 1 = HDR formats, level 2 = the cursor flag). `cursor_blend_for` and the `gamescope_cursor` resolver both consult it through one helper, because they have to agree: the reader without the blend is a wasted X11 connection, the blend without the reader is a stream with no pointer, and both together with a gamescope that paints its own would draw two. ⚠ The two indirect spawn modes carry the flag through `PF_HDR_ARGS`, so this shares a dependency with the HDR flags: a session that ignores `GAMESCOPE_BIN`/`PATH` and execs the distro's gamescope gets neither. HDR fails loudly there (negotiation timeout + SDR latch); a missing cursor would be silent. Noted in packaging/gamescope/README.md as worth a post-spawn `/proc/<pid>/cmdline` check if it ever bites. |
||
|
|
d6818263ce |
feat(gamescope): a build of gamescope whose capture output can be HDR
gamescope's built-in PipeWire node has always been SDR-only: it offers BGRx and NV12, and `paint_pipewire()` hardcodes a Gamma-2.2 composite with the SDR screenshot LUT set. So an HDR game reaches punktfunk already tone-mapped down, and the whole gamescope backend streams 8-bit no matter what the client can decode. Games CAN render HDR on a headless gamescope today — only the capture half is missing. Carry the two patches that close it (packaging/gamescope/patches): the node additionally offers `xRGB_210LE`/`xBGR_210LE` with MANDATORY SMPTE ST.2084 + BT.2020 props, mapped to the same 10-bit capture texture the HDR AVIF screenshot path already allocates, and `paint_pipewire()` composites into them with the HDR screenshot LUTs + `EOTF_PQ` — which is exactly the in-tree `bHDRScreenshot` branch. The new formats are listed LAST, so every existing consumer keeps negotiating the 8-bit stream bit-for-bit. Offered upstream against ValveSoftware/gamescope#2126. Ship it as `punktfunk-gamescope`, beside the distro's own binary rather than replacing it: a Bazzite sysext payload (`build-sysext.sh --gamescope`, which refuses a binary without the marker), an Arch package, a nix derivation + `services.punktfunk.host.gamescopeHdr`, and one distro-agnostic build script the rest call. The second patch stamps `+pfhdr1` into the `--version` banner. That is not cosmetic: punktfunk fixes a session's bit depth in the Welcome, before the display exists and with no way to take it back, so its capability answer has to be a static property of the binary it will spawn. |