fix(youko): add ROCm OpenCL so Jellyfin can tone-map HDR (#328)

* fix(youko): add ROCm OpenCL so Jellyfin can tone-map HDR

Jellyfin's HDR/DoVi transcodes use ffmpeg's `tonemap_opencl`, but only
Mesa was installed via `hardware.graphics.enable`, so no OpenCL ICD was
registered. ffmpeg then failed to create an OpenCL device ("Failed to
get number of OpenCL platforms: -1001") and aborted with exit code 237,
leaving HDR titles unplayable.

Add `rocmPackages.clr.icd` to `hardware.graphics.extraPackages`; it
ships the ICD for the Barceló iGPU (reported as `gfx90c`) under
/run/opengl-driver/etc/OpenCL/vendors, where `ocl-icd` (built with
`--enable-custom-vendordir`) finds it.

The Barceló iGPU only manages ~0.8x realtime for a 4K HDR -> 1080p
tone-mapped transcode, so playback can still buffer; this only makes
such titles playable at all.

* fix(youko): allow /dev/kfd so Jellyfin OpenCL can reach the GPU

The jellyfin module's `DeviceAllow` whitelist only permits the VA-API
render node (`/dev/dri/renderD128`). ROCm's OpenCL runtime opens
`/dev/kfd`, so even with the ICD installed OpenCL device creation failed
("No matching devices found") and HDR transcodes still aborted with exit
code 237.

Add `/dev/kfd rw` to the whitelist; list definitions merge with the
module's entry. Verified under the unit's sandbox (PrivateUsers,
PrivateTmp) that OpenCL init then succeeds as the jellyfin user.
This commit is contained in:
ryan4yin | 二花 authored and GitHub committed 2026-09-29 19:52:27 +08:00
1 parent 2401727315
commit 8ef52e2cf7
1 file changed
+15
@@ -27,6 +27,14 @@ in
# (and therefore VA-API) is missing.
hardware.graphics.enable = true;
# HDR/DoVi transcoding needs OpenCL for `tonemap_opencl`. With only Mesa
# installed, ffmpeg cannot create an OpenCL device (`Failed to get number of
# OpenCL platforms: -1001`) and the transcode aborts with exit code 237, so
# HDR titles fail to play. ROCm's clr provides the ICD for the Barceló iGPU
# (reported as `gfx90c`); `ocl-icd` finds it under
# /run/opengl-driver/etc/OpenCL/vendors.
hardware.graphics.extraPackages = [ pkgs.rocmPackages.clr.icd ];
services.jellyfin = {
enable = true;
@@ -96,4 +104,11 @@ in
# before it is mounted. The module's own RequiresMountsFor entries for
# config/log/cache are merged with these list definitions.
systemd.services.jellyfin.unitConfig.RequiresMountsFor = [ mediaDir ];
# ROCm's OpenCL runtime (used for HDR tone mapping via `tonemap_opencl`)
# reaches the GPU through /dev/kfd. The module's device whitelist only allows
# the VA-API render node, so OpenCL init fails and HDR transcodes abort with
# exit code 237. Allow the compute node too (list definitions merge with the
# module's entry).
systemd.services.jellyfin.serviceConfig.DeviceAllow = [ "/dev/kfd rw" ];
}