


ダイレクトレンダリングインフラストラクチャ(DRI )は、現代のLinuxグラフィックススタックを構成するフレームワークであり、特権を持たないユーザー空間プログラムが他のプログラムと競合することなくグラフィックスハードウェアにコマンドを発行できるようにします。[ 6 ] DRIの主な用途は、OpenGLのMesa実装にハードウェアアクセラレーションを提供することです。DRIは、ディスプレイサーバーが実行されていないフレームバッファコンソールでOpenGLアクセラレーションを提供するようにも適応されています。[ 7 ]
DRIの実装は、 Xサーバーとその関連クライアントライブラリ、Mesa 3D、およびDirect Rendering Managerカーネルサブシステムに分散しています。[ 6 ]すべてのソースコードはオープンソースソフトウェアです。
従来のX Window Systemアーキテクチャでは、X サーバーだけがグラフィックス ハードウェアへの排他的アクセス権を持ち、フレーム バッファ上で実際のレンダリングを実行します。X クライアントは、レンダリング コマンドをディスパッチするために X サーバーと通信するだけです。これらのコマンドはハードウェアに依存しません。つまり、X11 プロトコルはグラフィックス デバイスを抽象化するAPIを提供するため、X クライアントは基盤となるハードウェアの詳細を知る必要も、気にする必要もありません。ハードウェア固有のコードは、デバイス依存 Xと呼ばれる部分にあります。これは、各タイプのビデオ カードまたはグラフィックス アダプタを管理する X サーバーの一部であり、ビデオドライバまたはグラフィックス ドライバとも呼ばれます。
3Dレンダリングの台頭により、このアーキテクチャの限界が明らかになりました。3Dグラフィックスアプリケーションは大量のコマンドとデータを生成する傾向があり、それらはすべてレンダリングのためにXサーバーにディスパッチする必要があります。XクライアントとXサーバー間のプロセス間通信(IPC)が増加するにつれて、3Dレンダリングのパフォーマンスが低下し、Xドライバ開発者は最新のグラフィックスカードの3Dハードウェア機能を活用するには、新しいIPCレスアーキテクチャが必要であると結論付けました。Xクライアントは、他のプロセスに頼るのではなく、グラフィックスハードウェアに直接アクセスすることで、すべてのIPCオーバーヘッドを削減する必要があります。このアプローチは、従来のXアーキテクチャが提供する「間接レンダリング」とは対照的に、「直接レンダリング」と呼ばれます。Direct Rendering Infrastructureは、当初、あらゆるXクライアントがこの「直接レンダリング」アプローチを使用して3Dレンダリングを実行できるようにするために開発されました。
DRI を使用して X クライアント内で高速化された 2D 直接レンダリングを実装することを妨げるものは何もありません。[ 3 ]単に、2D 間接レンダリングのパフォーマンスが十分であったため、誰もそうする必要がなかっただけです。
ダイレクトレンダリングインフラストラクチャの基本アーキテクチャは、3つの主要コンポーネントで構成されています。[ 8 ]
オリジナルの DRI アーキテクチャでは、当時のビデオ カードのメモリ サイズのため、スクリーンのフロント バッファとバック バッファ(補助深度バッファとステンシル バッファも含む) のインスタンスが 1 つだけあり、すべての DRI クライアントと X サーバーで共有されていました。[ 11 ] [ 12 ]それらはすべてバック バッファに直接レンダリングされ、垂直ブランキング インターバルタイムにフロント バッファと交換されました。[ 11 ]バック バッファにレンダリングするには、DRI プロセスはレンダリングがウィンドウ用に予約された領域にクリップされるようにする必要がありました。[ 11 ] [ 12 ]
X Server との同期は、シグナルと SAREA と呼ばれる共有メモリ バッファを介して行われました。[ 12 ] DRMデバイスへのアクセスは排他的であったため、DRI クライアントはレンダリング操作の開始時にそれをロックする必要がありました。その間、X Server を含むデバイスの他のユーザーはブロックされ、両方の操作間で競合が発生しない場合でも、現在のレンダリング操作の終了時にロックが解除されるまで待つ必要がありました。 [ 12 ]もう 1 つの欠点は、現在の DRI プロセスがデバイスのロックを解除した後、操作がメモリ割り当てを保持しなかったため、テクスチャなどのグラフィックス メモリにアップロードされたデータは、後続の操作で失われ、グラフィックス パフォーマンスに大きな影響を与えたことです。
現在では、DRI1は完全に時代遅れとみなされており、使用すべきではありません。
Compizのような合成ウィンドウマネージャの人気が高まったため、X クライアントが直接レンダリングを実行しながら「オフスクリーン ピクスマップ」へのリダイレクトもサポートできるように、Direct Rendering Infrastructure を再設計する必要がありました。通常の X クライアントは、レンダリング ターゲットとして X サーバーが提供する別のピクスマップ(いわゆるオフスクリーン ピクスマップ)へのリダイレクトを既に尊重していましたが、DRI クライアントは引き続き共有バックバッファに直接レンダリングを実行し、合成ウィンドウマネージャを事実上バイパスしていました。[ 11 ] [ 13 ]最終的な解決策は、DRI がレンダリング バッファを処理する方法を変更することでした。これにより、新しい一連の操作を備えたまったく異なる DRI 拡張機能と、Direct Rendering Managerの大幅な変更が実現しました。[ 3 ]新しい拡張機能は「DRI2」と名付けられましたが、これは後のバージョンではなく、元の DRI と互換性のない別の拡張機能です。実際、両方とも長い間 X サーバー内で共存していました。
DRI2では、単一の共有(バック)バッファの代わりに、各DRIクライアントは、ハードウェアアクセラレーションを使用してウィンドウコンテンツをレンダリングするために、それぞれ独自のプライベートバックバッファ[ 11 ] [ 12 ] と、それに関連付けられた深度バッファおよびステンシルバッファを取得します。DRIクライアントは、それを偽の「フロントバッファ」[ 12 ]と交換します。この偽の「フロントバッファ」は、合成ウィンドウマネージャによって、 VBLANK間隔で実際のフロントバッファと交換される最終的なスクリーンバックバッファを構成(構築)するためのソースの1つとして使用されます。
これらの新しいバッファをすべて処理するために、ダイレクトレンダリングマネージャは新しい機能、具体的にはグラフィックスメモリマネージャを組み込む必要がありました。DRI2は当初、実験的なTTMメモリマネージャを使用して開発されましたが[ 11 ] [ 13 ] 、後にGEMが決定的なDRMメモリマネージャとして選ばれたため、GEMを使用するように書き直されました[ 14 ] 。新しいDRI2内部バッファ管理モデルは、元のDRI実装に存在していた2つの主要なパフォーマンスボトルネックも解決しました。
DRI2 では、ウィンドウのプライベート オフスクリーン バッファ (バック バッファ、フェイク フロント バッファ、デプス バッファ、ステンシル バッファなど) の割り当ては、X サーバー自体によって行われます。[ 15 ] [ 16 ] DRI クライアントは、DRI2 拡張機能で使用可能なDRI2GetBuffersやDRI2GetBuffersWithFormatなどの操作を呼び出すことで、これらのバッファを取得してウィンドウにレンダリングします。[ 3 ]内部的には、DRI2 は、 GEM APIによって提供されるグローバル ハンドルの一種であるGEM 名を使用して、X11 プロトコルを介してこれらのバッファへの「参照」を渡します。GEM API は、DRM デバイスにアクセスする 2 つのプロセスが同じバッファを参照できるようにします。[ 16 ] X サーバーがウィンドウのレンダリング バッファの割り当てを担当する理由は、GLX 拡張機能により、複数の X クライアントが同じウィンドウで協調してOpenGLレンダリングを実行できるためです。 [ 15 ]このように、X サーバーはレンダリング プロセス全体にわたってレンダリング バッファのライフサイクル全体を管理し、安全に再利用または破棄できるタイミングを把握します。ウィンドウのサイズ変更が行われると、X サーバーは新しいウィンドウ サイズに一致する新しいレンダリング バッファを割り当て、InvalidateBuffers イベントを使用してウィンドウにレンダリングしている DRI クライアントに変更を通知し、新しいバッファの GEM 名を取得する責任も負います。[ 15 ]
DRI2拡張機能は、DRIクライアントに対して、どのDRMデバイスとドライバを使用するかを調べる( DRI2Connect )、またはDRMデバイスのレンダリング機能とバッファ機能を使用できるようにXサーバーで認証を受ける(DRI2Authenticate)など、その他のコア操作を提供します。[ 3 ]レンダリングされたバッファの画面への表示は、DRI2CopyRegionおよびDRI2SwapBuffersリクエストを使用して実行されます。DRI2CopyRegionは、偽のフロントバッファと実際のフロントバッファの間でコピーを実行するために使用できますが、垂直ブランキング間隔との同期は提供されないため、ティアリングが発生する可能性があります。一方、DRI2SwapBuffersは、サポートされていて両方のバッファが同じサイズである場合は、バックバッファとフロントバッファの間でVBLANK同期スワップを実行し、そうでない場合はコピー( blit )を実行します。[ 3 ] [ 15 ]
DRI2はオリジナルのDRIに比べて大幅に改善されたものの、新しい拡張機能によっていくつかの新たな問題も生じた。[ 15 ] [ 16 ] 2013年には、これらの問題を解決するために、DRI3として知られるDirect Rendering Infrastructureの第3版が開発された。[ 17 ]
DRI3とDRI2の主な違いは以下のとおりです。
クライアント側でのバッファ割り当ては、複数の GLX アプリケーションが同じウィンドウで協調してレンダリングすることができなくなるという意味でGLX の前提を破ります。プラス面としては、DRI クライアントがバッファのライフサイクル全体にわたって自身のバッファを管理するという事実が多くの利点をもたらします。たとえば、DRI3 クライアントはレンダリング バッファのサイズが常にウィンドウの現在のサイズと一致することを容易に保証できるため、DRI2 でウィンドウのリサイズを悩ませていたクライアントとサーバー間のバッファ サイズの同期の欠如によるアーティファクトを排除できます。[ 15 ] [ 16 ] [ 18 ]また、DRI3 クライアントは X サーバーがレンダリング バッファを送信するのを待つ余分なラウンドトリップを節約できるため、パフォーマンスが向上します。[ 16 ] DRI3 クライアント、特にコンポジタ ウィンドウマネージャは、以前のフレームの古いバッファを保持し、それをウィンドウの破損した部分のみをレンダリングするためのベースとして再利用することで、別のパフォーマンス最適化を実現できます。[ 15 ] [ 16 ] DRI3拡張機能は、新しい特定のバッファ形式をサポートするために変更する必要がなくなりました。これは、DRIクライアントドライバとDRMカーネルドライバの間で直接処理されるようになったためです。[ 15 ]一方、ファイルディスクリプタを使用することで、カーネルは、参照のない未使用のGEMバッファオブジェクトを安全にクリーンアップできます。 [ 15 ] [ 16 ]
技術的には、DRI3 は「DRI3」拡張機能と「Present」拡張機能の 2 つの拡張機能で構成されています。[ 17 ] [ 19 ] DRI3 拡張機能の主な目的は、DRI クライアントと X サーバー間で直接レンダリングされたバッファを共有するメカニズムを実装することです。[ 18 ] [ 19 ] [ 20 ] DRI クライアントは GEM バッファ オブジェクトをレンダリング ターゲットとして割り当てて使用しますが、X サーバーはこれらのレンダリング バッファを「pixmap」と呼ばれるタイプの X11 オブジェクトを使用して表現します。DRI3 は、DRI3PixmapFromBufferとDRI3BufferFromPixmapという 2 つの操作を提供します。1 つは GEM バッファ オブジェクト (「DRI クライアント スペース」) から (「X サーバー スペース」) ピクスマップを作成する操作、もう 1 つは逆の操作として X ピクスマップから GEM バッファ オブジェクトを取得する操作です。[ 18 ] [ 19 ] [ 20 ]これらの DRI3 操作では、GEM バッファ オブジェクトはGEM 名ではなくDMA-BUFファイル ディスクリプタとして渡されます。 DRI3 では、DRI クライアントと X サーバー間で同期オブジェクトを共有する方法も提供されており、共有バッファへのシリアルアクセスが可能です。[ 19 ] DRI2 とは異なり、最初のDRI3Open操作(どの DRM デバイスを使用するかを知るためにすべての DRI クライアントが最初に要求する必要がある操作)では、デバイス ノードのファイル名ではなく、既に開いているファイル ディスクリプタがデバイス ノードに返され、必要な認証手順は X サーバーによって事前に実行されています。[ 18 ] [ 19 ]
DRI3 は、レンダリングされたバッファを画面に表示するメカニズムを提供しませんが、別の拡張機能であるPresent拡張機能に依存しています。[ 20 ] Presentという名前は、その主なタスクがバッファを画面に「表示」すること、つまりクライアント アプリケーションから提供されたレンダリングされたバッファの内容を使用してフレーム バッファの更新を処理することにあるためです。[ 19 ]画面の更新は、ティアリングなどの表示アーティファクトを避けるために、通常はVBLANK インターバル中に適切なタイミングで行う必要があります。Present は、画面の更新を VBLANK インターバルに同期させることも処理します。[ 21 ]また、イベントを使用して各バッファが実際に画面に表示される瞬間を X クライアントに通知し、クライアントがレンダリング プロセスを現在の画面のリフレッシュ レートに同期できるようにします。
Present は、画面更新のソースとして任意の X ピクスマップを受け入れます。[ 21 ]ピクスマップは標準の X オブジェクトであるため、Present は直接レンダリングを実行する DRI3 クライアントだけでなく、あらゆる手段でピクスマップにレンダリングを行う任意の X クライアントでも使用できます。[ 18 ]例えば、既存のGLベースではないGTK+およびQtアプリケーションのほとんどは、 XRenderを使用してダブルバッファリングされたピクスマップ レンダリングを行っていました。Present 拡張機能は、これらのアプリケーションでも使用して、効率的でティアリングのない画面更新を実現できます。これが、Present が DRI3 の一部ではなく、独立した拡張機能として開発された理由です。[ 18 ]
Presentは、GL以外のXクライアントがVBLANKと同期できるようにするだけでなく、他にも利点があります。PresentはDRI2よりもバッファのスワップが効率的なため、DRI3グラフィックスのパフォーマンスが向上しています。[ 19 ] Presentによって提供される新機能に基づいて、DRI2では利用できなかった多くのOpenGL拡張機能がサポートされるようになりました。[ 19 ]
Present は、X クライアントに対して主に 2 つの操作を提供します。ピクスマップの内容の一部または全部を使用してウィンドウの領域を更新する ( PresentPixmap ) 操作と、クライアントが通知を受け取りたい特定のウィンドウに関連するプレゼンテーション イベントのタイプを設定する ( PresentSelectInput ) 操作です。[ 19 ] [ 21 ]ウィンドウが X クライアントに通知できるプレゼンテーション イベントは 3 つあります。進行中のプレゼンテーション操作(通常はPresentPixmapの呼び出しから)が完了したとき ( PresentCompleteNotify )、 PresentPixmap操作で使用されるピクスマップが再利用できる状態になったとき ( PresentIdleNotify )、ウィンドウ構成(主にウィンドウ サイズ)が変更されたとき ( PresentConfigureNotify ) です。[ 19 ] [ 21 ] PresentPixmap操作がフロント バッファに直接コピー ( blit ) するか、バック バッファ全体をフロント バッファとスワップするかは、DRI2 のように X クライアントが明示的に選択するのではなく、Present 拡張機能の実装の内部の詳細です。
オープンソースのDRIドライバはいくつか開発されており、ATI Mach64、ATI Rage128、ATI Radeon、3dfx Voodoo3~Voodoo5、Matrox G200~G400、SiS 300シリーズ、Intel i810~i965、S3 Savage、VIA UniChromeグラフィックスチップセット、Nvidia向けのnouveauなどが含まれます。一部のグラフィックスベンダーは、 ATIやPowerVR Kyroなど、クローズドソースのDRIドライバを開発しています。
DRIの様々なバージョンは、Linuxカーネル、FreeBSD、NetBSD、OpenBSD、OpenSolarisなど、様々なオペレーティングシステムに実装されている。
このプロジェクトは、Precision Insight の Jens Owen と Kevin E. Martin によって開始されました ( Silicon GraphicsとRed Hatの資金提供を受けています)。[ 1 ] [ 22 ]最初はXFree86 4.0の一部として広く利用可能になり[ 1 ] [ 23 ]、現在はX.Org Serverの一部となっています。現在はフリーソフトウェアコミュニティによって維持されています。
DRI2 の開発は、2007 年の X Developers' Summit でKristian Høgsbergの提案から始まりました。[ 24 ] [ 25 ] Høgsberg 自身が新しい DRI2 拡張機能とMesaおよびGLXの変更を作成しました。[ 26 ] 2008 年 3 月には DRI2 はほぼ完成していたが、[ 27 ] [ 28 ] [ 29 ] X.Org Serverバージョン 1.5 [ 14 ]には組み込めず、2009 年 2 月のバージョン 1.6 まで待たなければならなかった。[ 30 ] DRI2 拡張機能は、2009 年 10 月の X11R7.5 リリースに正式に含まれた。[ 31 ] DRI2 プロトコルの最初の公開バージョン (2.0) は、2009 年 4 月に発表された。[ 32 ]それ以降、いくつかの改訂が行われ、最新のものは 2012 年 7 月のバージョン 2.8 である。[ 4 ]
DRI2 にはいくつかの制限があったため、2012 年の X.Org 開発者会議で Keith Packard と Emma Anholt によって DRI-Next と呼ばれる新しい拡張機能が提案されました。[ 15 ]この拡張機能は、2013 年のLinux.conf.auで DRI3000 として再び提案されました。 [ 16 ] [ 17 ] DRI3 と Present 拡張機能は 2013 年に開発され、2013 年 12 月からの X.Org Server 1.15 リリースに統合されました。[ 33 ] [ 34 ] DRI3 プロトコルの最初の唯一のバージョン (1.0) は、2013 年 11 月にリリースされました。[ 5 ]