PS5やWindows PCの様にLinuxでHDR対応コンテンツを楽しめるのかですが、結論から言えば、一応可能です。 ただ、そんなにお手軽かというとそうではないし、それなりに制約があります。また、自分の目ではちゃんとなっている様に見えますが本当に想定された色が出てるのかというと良く分からんという感じではあります。
という訳で、多少問題はあるかもしれませんが可能は可能なので、その実現方法について紹介します。
LinuxのHDRサポート状況
参考: HDR monitor support - ArchWiki
現状、デスクトップ環境レベルでHDRをサポートしているのはKDE Plasmaがwaylandセッションで実験的にサポートしているだけです。 X.orgにおいてはサポートされる見込みは恐らくありません。
GNOMEデスクトップはサポートに向けて頑張っている最中の様です。
DRMレベルでHDR metadataを扱うことは可能です。一般的なuserspaceのクライアントで利用可能なものはありませんが、特定のソフトウェアで対応しているものがあります。
自分が利用しているHyprlandというwaylandのWMは実装が進められている様です。今後に期待したい。(https://github.com/hyprwm/aquamarine/pull/112)
という訳で、現時点でまともにHDRコンテンツを扱う方法は自分が知ってる限りではgamescopeを利用する方法だけです。
gamescopeについて
gamescopeはValveSoftwareがSteamOS向けに開発したWindow Managerです。 gamescopeは単体のGUIアプリを起動するのに特化したWindow Managerでゲームフレームの描画に最適化されています。そのため、通常のデスクトップ環境で起動するよりもゲームフレームの描画がスムーズになります。
gamescopeにはembeddedモードとnestedモードという二種類のモードがあり、通常のデスクトップ環境で起動するとnestedモードになります。Xwaylandのサンドボックスデスクトップを起動して既存のデスクトップ環境と干渉することを避け、任意の解像度とリフレッシュレートを偽装することができます。
embeddedモードではDRM/KMSを利用してXwaylandを起動し、この上でゲームを起動することで余計なフレームコピーを回避して描画を高速化しています。
このembeddedモードでDRM/KMSを利用する場合において、HDRを有効化できます。
Steamをプレイする場合の実行手順
最初にgamescopeのhelpを紹介しておきます。
gamescope --help
[gamescope] [Info] console: gamescope version (gcc 14.2.1)
usage: gamescope [options...] -- [command...]
Options:
--help show help message
-W, --output-width output width
-H, --output-height output height
-w, --nested-width game width
-h, --nested-height game height
-r, --nested-refresh game refresh rate (frames per second)
-m, --max-scale maximum scale factor
-S, --scaler upscaler type (auto, integer, fit, fill, stretch)
-F, --filter upscaler filter (linear, nearest, fsr, nis, pixel)
fsr => AMD FidelityFX™ Super Resolution 1.0
nis => NVIDIA Image Scaling v1.0.3
--sharpness, --fsr-sharpness upscaler sharpness from 0 (max) to 20 (min)
--expose-wayland support wayland clients using xdg-shell
-s, --mouse-sensitivity multiply mouse movement by given decimal number
--backend select rendering backend
auto => autodetect (default)
drm => use DRM backend (standalone display session)
sdl => use SDL backend
headless => use headless backend (no window, no DRM output)
wayland => use Wayland backend
--cursor path to default cursor image
-R, --ready-fd notify FD when ready
--rt Use realtime scheduling
-T, --stats-path write statistics to path
-C, --hide-cursor-delay hide cursor image after delay
-e, --steam enable Steam integration
--xwayland-count create N xwayland servers
--prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)
--force-orientation rotate the internal display (left, right, normal, upsidedown)
--force-windows-fullscreen force windows inside of gamescope to be the size of the nested display (fullscreen)
--cursor-scale-height if specified, sets a base output height to linearly scale the cursor against.
--hdr-enabled enable HDR output (needs Gamescope WSI layer enabled for support from clients)
If this is not set, and there is a HDR client, it will be tonemapped SDR.
--sdr-gamut-wideness Set the 'wideness' of the gamut for SDR comment. 0 - 1.
--hdr-sdr-content-nits set the luminance of SDR content in nits. Default: 400 nits.
--hdr-itm-enable enable SDR->HDR inverse tone mapping. only works for SDR input.
--hdr-itm-sdr-nits set the luminance of SDR content in nits used as the input for the inverse tone mapping process.
Default: 100 nits, Max: 1000 nits
--hdr-itm-target-nits set the target luminace of the inverse tone mapping process.
Default: 1000 nits, Max: 10000 nits
--framerate-limit Set a simple framerate limit. Used as a divisor of the refresh rate, rounds down eg 60 / 59 -> 60fps, 60 / 25 -> 30fps. Default: 0, disabled.
--mangoapp Launch with the mangoapp (mangohud) performance overlay enabled. You should use this instead of using mangohud on the game or gamescope.
Nested mode options:
-o, --nested-unfocused-refresh game refresh rate when unfocused
-b, --borderless make the window borderless
-f, --fullscreen make the window fullscreen
-g, --grab grab the keyboard
--force-grab-cursor always use relative mouse mode instead of flipping dependent on cursor visibility.
--display-index forces gamescope to use a specific display in nested mode.
Embedded mode options:
-O, --prefer-output list of connectors in order of preference
--default-touch-mode 0: hover, 1: left, 2: right, 3: middle, 4: passthrough
--generate-drm-mode DRM mode generation algorithm (cvt, fixed)
--immediate-flips Enable immediate flips, may result in tearing
--adaptive-sync Enable adaptive sync if available (variable rate refresh)
Debug options:
--disable-layers disable libliftoff (hardware planes)
--debug-layers debug libliftoff
--debug-focus debug XWM focus
--synchronous-x11 force X11 connection synchronization
--debug-hud paint HUD with debug info
--debug-events debug X11 events
--force-composition disable direct scan-out
--composite-debug draw frame markers on alternating corners of the screen when compositing
--disable-color-management disable color management
--disable-xres disable XRes for PID lookup
--hdr-debug-force-support forces support for HDR, etc even if the display doesn't support it. HDR clients will be outputted as SDR still in that case.
--hdr-debug-force-output forces support and output to HDR10 PQ even if the output does not support it (will look very wrong if it doesn't)
--hdr-debug-heatmap displays a heatmap-style debug view of HDR luminence across the scene in nits.
Reshade shader options:
--reshade-effect sets the name of a reshade shader to use in either /usr/share/gamescope/reshade/Shaders or ~/.local/share/gamescope/reshade/Shaders
--reshade-technique-idx sets technique idx to use from the reshade effect
Steam Deck options:
--mura-map Set the mura compensation map to use for the display. Takes in a path to the mura map.
Keyboard shortcuts:
Super + F toggle fullscreen
Super + N toggle nearest neighbour filtering
Super + U toggle FSR upscaling
Super + Y toggle NIS upscaling
Super + I increase FSR sharpness by 1
Super + O decrease FSR sharpness by 1
Super + S take a screenshot
Super + G toggle keyboard grab
オプションの中に--hdr-enabledなどがあることが分かりますが、この辺を利用します。
embeddedモードで起動しなければならないので、まずCTRL+ALT+F2(〜F6)ホットキーを使って、デスクトップ環境が起動していないセッションに切り替えます。どの番号が空いてるかは環境に依りますが、大抵F1かF7でデスクトップが起動していると思うのでF2は空いてるでしょう。
コンソール上で以下のコマンドを使ってsteamを起動します。
ENABLE_GAMESCOPE_WSI=1 ENABLE_HDR_WSI=1 DXVK_HDR=1 gamescope -e --xwayland-count 2 -o "DP-1,*" --hdr-enabled --hdr-itm-enable -- steam -gamepadui
DP-1の部分は自身が接続しているディスプレイのポートに合わせて読み替えてください。
WSI関連の環境変数はgamescopeのHDR対応の有効化とvulkan APIのHDR対応の有効化に必要な様です。
DXVK_HDR=1は、ProtonやWineで起動するゲームアプリケーションのHDR対応を有効化するために必要で、VulkanでエミュレートしているDirectXのAPIに対してHDR機能の有効化を指示する環境変数です。この環境変数を付けて起動すれば、対応しているゲームならゲーム内の設定でHDRの有効・無効が切り替えられる様になるはずです。
上記のコマンドでsteamが起動すると、この時点でディスプレイのHDRモードが有効になるはずです。
この状態で、steamのゲームを起動し、DXVK_HDRの環境変数が正しく渡っていれば、HDR対応のゲームをHDRモードでプレイできるはずです。もしゲーム内まで環境変数が伝播していなければ、steamtinkerlaunchなどの起動ラッパーを使うか、steam上の設定で実行コマンドに環境変数を付与すれば対応できるでしょう。
自分の環境ではサイバーパンク2077とDMC5において、HDRモードでプレイすることができました。
DRMで直接steamを起動していることによる制約
この状態だとディスプレイが1枚しか使えません。ゲームをプレイしつつサブディスプレイでWebブラウザを表示するなどは不可能です。
CTRL+ALT+F1でデスクトップ環境が起動しているセッションに戻ることで通常のデスクトップアプリを操作することはできます。この時、ディスプレイのHDRモードが自動でオフになったりはしないので、やたらビビッドな色で表示されることになりますが、攻略サイトを見たりすることは出来ると思います。
steamを落としてgamescopeプロセスを終了したらディスプレイのHDRモードが解除されるはずです。
HDR動画を試聴する
世の中にそんなにHDR対応の動画コンテンツは無いんですが、mpvとgamescopeを組み合わせることでHDRモードで動画を再生することが出来ます。
mpvのconfigに以下の内容を追加します。
[hdr] target-colorspace-hint=yes inverse-tone-mapping=yes target-prim=bt.2020 target-trc=pq target-peak=600
大事なのはtarget-colorspace-hintとinverse-tone-mappingです。
設定を追加したら、以下の様にmpvを起動します。
ENABLE_GAMESCOPE_WSI=1 ENABLE_HDR_WSI=1 gamescope -e --xwayland-count 2 -O "DP-1,*" --hdr-enabled -- mpv --profile=hdr <movie file>
これでディスプレイがHDRモードに切り替わった状態でmpvが起動し、tone-mappingによるHDR->SDR変換ではなくHDRの色情報のまま動画が表示できるはずです。
多分、色的にも正しいと思うのですが、そもそも理想的な色状態に確信が無いので、ちょっと何とも言えないところはありますが……。
という訳で、gamescopeを使って頑張れば現状のLinuxでもHDR対応コンテンツを楽しむことは出来ると思います。
この記事が誰かの参考になれば幸いです。