このページの目次

DRM とグラフィックス

Linux には2つのグラフィックススタックがあります。fbdev(1990年代)は単にビデオメモリにピクセルを書き込むだけであり、DRM(2010年代以降)は最新の GPU インターフェースを完全に提供します。KMS は表示モード設定を管理し(atomic modesetting によりマルチモニター構成がアトミック操作になります)、GEM はビデオメモリ割り当てとプロセス間共有を管理します(DMA-BUF は GPU と Wayland compositor の間でバッファのコピーゼロ転送を行います)。amdgpu と i915 はこれらのサブシステムの最大の利用者です。 カーネルバージョン: 2.6 ~ 6.x

概要

Linux には2つのグラフィックススタックがあります。fbdev(framebuffer、1990年代)と DRM(Direct Rendering Manager、2010年代以降)です。fbdev は単にビデオメモリにピクセルを書き込むだけであり、GPU アクセラレーション、マルチプレーン合成、vsync 同期はありません。DRM は最新の GPU インターフェースを完全に提供します。モード設定 (KMS)、ビデオメモリ管理 (GEM)、GPU コマンド送信 (レンダリング)、およびデバイス間バッファ共有 (DMA-BUF) です。

ユーザー空間では /dev/dri/card0(メイン GPU)と /dev/dri/renderD128(レンダリング専用、モード設定権限不要)が見えます。Mesa および Vulkan ドライバーは、これらのデバイスファイルを通じてカーネルと通信します。

DRM の3つのコアサブシステム

KMS (Kernel Mode Setting): 表示パイプライン

KMS は「どのようにピクセルを表示器に送るか」を管理します。関与するハードウェア抽象化は以下の通りです。

  • CRTC (ブラウン管コントローラー——歴史的な名称が保持されています): スキャンコントローラー。フレームバッファからピクセルを読み取り、タイミングに従ってビデオ信号を生成します。各 CRTC が1つのモニターを駆動します。
  • Encoder: CRTC のピクセルストリームを物理インターフェース形式にエンコードします(HDMI 用 TMDS、ノートパソコンパネル用 LVDS、DisplayPort など)。
  • Connector: 物理ポート(HDMI-A-1, DP-2, eDP-1)。モニター熱挿抜(HPD)を検出し、EDID(モニター能力記述:対応解像度、リフレッシュレート)を読み取ります。
  • Plane: オーバーレイ。Primary plane = メインフレームバッファ。Overlay plane = ハードウェアアクセラレーションされたオーバーレイ(ビデオ再生、マウスカーソル)。最新の GPU には複数の plane があり、ハードウェア合成が可能です。

これらのオブジェクトはパイプライン CRTC → Encoder → Connector を構成します。ユーザー空間は DRM_IOCTL_MODE_* ioctl を通じてこのパイプラインを設定します。

Atomic Modesetting

旧 API はパラメータを段階的に設定していました。まず CRTC モードを変更し、次にコネクタを変更し、というように、各ステップの中間状態では画面がちらつく可能性があります。Atomic modesetting は、表示状態全体を drm_atomic_state 構造体にカプセル化します。

// atomic commit の構築:
struct drm_atomic_state *state = drm_atomic_state_alloc(dev);
// CRTC/plane/connector のプロパティ変更を追加
drm_atomic_commit(state);
// → 検証 (check) → 通過した場合、vblank 期間中にアトミックに適用 → ちらつきのない遷移

重要な性質は「全か無か」です。検証に失敗した場合(解像度がサポートされていないなど)、コミット全体が拒否され、表示は変更されません。これにより、「デバイスが半分だけ変更された」という中間状態が排除されます。

GEM (Graphics Execution Manager): ビデオメモリ管理

GPU メモリは単純な malloc ではありません。VRAM(ビデオメモリ)、GTT(Graphics Translation Table、システムメモリの一部が可視)、および各エンジンでの可視性制約が関与します。GEM はドライバーに依存しないバッファ管理を提供します。

// GPU バッファの割り当て(ドライバー実装による):
struct drm_gem_object *obj = drm_gem_object_create(dev, size);
// → ハンドルを返す → ユーザー空間で mmap → バッファコンテンツにアクセス

重要な機能:DMA-BUF。GPU バッファはファイルディスクリプタ (drm_prime_handle_to_fd) としてエクスポートできます。別の GPU や V4L2 デバイスは、この fd を通じてインポートします。これにより、⁠デバイス間共有でのコピーゼロが実現します。Wayland compositor は、クライアントがレンダリングしたバッファを CPU 経由でコピーすることなく、直接表示エンジンに送るためにこれを利用しています。

GPU ドライバーアーキテクチャ: KMD と UMD の分離

最新の GPU ドライバーは2つの部分に分かれています。

KMD (Kernel Mode Driver): amdgpu.ko, i915.ko, nouveau.ko。モード設定(表示)、ビデオメモリ管理(GEM/TTM)、コマンド送信(リングバッファ)、フェンス同期、ファームウェア管理を担当します。

UMD (User Mode Driver): Mesa (OpenGL/Vulkan) または NVIDIA のプロプライエタリドライバー。OpenGL/Vulkan API を GPU コマンドに変換し、シェーダーをコンパイルします。/dev/dri/renderD* を通じて通信し、モード設定権限や root 権限は不要です。

KMD が提供するものはインフラストラクチャ⁠(バッファの割り当て、コマンドの送信)であり、UMD が提供するものはアプリケーション API です。この分離により、Mesa はカーネルの更新とは独立して更新でき、新しい OpenGL バージョンのためにカーネルを再コンパイルする必要はありません。

fbdev から DRM への移行

fbdev は1990年代のフレームバッファインターフェースです。mmap(fbdev_fd) によってビデオメモリのマッピングを取得し、ピクセルを直接書き込みます。vsync、マルチプレーン、GPU アクセラレーションはありません。現代のシステムでは、古いプログラム(fbi, directfb など)との互換性のために、DRM 上で drm_fb_helper によって fbdev インターフェースがエミュレートされます。ただし、基盤は依然として DRM です。

参考

  • ソースコード⁠: drivers/gpu/drm/ (コア), drivers/gpu/drm/amd/ (amdgpu), drivers/gpu/drm/i915/, include/drm/, include/uapi/drm/
  • カーネルドキュメント⁠: Documentation/gpu/
  • Mesa: docs.mesa3d.org

キーワード: DRM, KMS, GEM, atomic modesetting, CRTC, plane, DMA-BUF, amdgpu, i915, fbdev, Wayland