OpenGLのダイレクトステートアクセスメカニズムの利点は何ですか?


11

私はopengl.orgで OpenGL 4.5ダイレクトステートアクセス(DSA)について読んでいますが、正しく機能しているかどうかはわかりません。

古い方法は効率が悪いことを暗示しているようです:

glBind(something)
glSetA(..)
glSetB(..)
glSetC(..)

新しい方法より:

glSetA(something, ..)
glSetB(something, ..)
glSetC(something, ..)

その見た目から、それぞれglSetglBind(something)その内部に含まれている必要があり、OpenGLがまだ状態マシンである場合、単一のに適用されたストリーム化された変更を利用できませんsomething

新しいDSAの背後にある理由と利点を説明してください。

回答:


21

その外観から、各glSetは内部にglBind(something)を含める必要があります

ではない正確に。以下のいくつかの段落で説明するように、これは逆です。

それが真実であったとしても、クライアントアプリからGLサーバー(別名ドライバー)へのGLコマンドには、通常の関数呼び出しと比較して、ディスパッチのオーバーヘッドが多いことに注意してください。DSA関数が既存の関数の単なるラッパーであると仮定した場合でも、それらはGLサーバー内に存在するラッパーであるため、オーバーヘッドが(少し)少なくなります。

OpenGLがまだ状態マシンである場合、単一の何かに適用されたストリーム化された変更を利用できません。

GPUはステートマシンではありません。GLステートマシンインターフェイスは、DSAのようなドライバーの内部をラップするエミュレーションであり、その逆ではありません。

ラッピングの1つの層(GLサーバーへの過度の呼び出しを必要とする層)を削除することは、たとえ小さなものであっても、明らかに有利です。

ステートマシンアプローチは、複数のスレッドを処理する場合にも意味がありません。このユースケースではGLは依然としてひどいですが、ドライバーはバックグラウンドでスレッドを使用することが多く、ステートマシンは、多くのスレッドの同期や、物事を確実に機能させるための非常に優れた並列アルゴリズム/構造を必要とします。

DSA拡張は、結局のところ、完全に新しいAPIではなく、既存の状態ベースのドキュメントに対する拡張であるため、状態の変化の観点からその操作をフレーズし続けているため、既存のGL仕様にプラグインする準備ができていなければなりませんでしたドキュメントの言語と用語。その既存の言語が最新のグラフィックスハードウェアAPIとしての仕事にかなりひどく適しているとしても。

新しいDSAの背後にある理由と利点を説明してください。

最大の理由は、古い方法が苦痛だったということです。それぞれがGLの状態を変更したり、GLの状態に依存する可能性のあるライブラリを一緒に構成することは非常に困難になりました。手続き型の状態管理ルートが深いため、GL APIをオブジェクト指向または機能的なスタイルで効率的にラップすることが難しくなり、APIをさまざまな非C言語でラップすることが困難になり、効率的なグラフィックデバイスラッパーを提供することも困難になりました。 Direct3Dからの抽象的なOpenGL。

2つ目は、前述のように、手続き型の状態マシンAPIのオーバーヘッドでした。

第3に、DSA機能は、効率の向上を可能にする古いAPIからセマンティクスを適切に変更しました。以前は変更可能であったものが不変になり、たとえば、GLサーバーから多くの簿記コードが削除されました。GLサーバーが可変オブジェクトを処理する必要がない場合は、アプリケーションによる呼び出しをハードウェアにディスパッチしたり、より早く(またはより並列的に)検証したりできます。

-

追加の正当化と説明は、EXT_direct_state_access拡張仕様に記載されています。

-

API設計に関連するハードウェアの変更はかなり多くあります。

OpenGLは1991年に遡ることを思い出してください。ターゲットハードウェアは、コンシューマーグレードのグラフィックカード(存在しないもの)ではなく、大きなCADワークステーションなどでした。その時代のハードウェアは、今日とはまったく異なるパフォーマンスエンベロープを備えていました。マルチスレッディングはまれであり、メモリバスとCPUの速度ギャップは少なく、GPUは固定関数の三角形レンダリングにすぎませんでした。

ますます多くの固定機能機能が追加されました。さまざまなライティングモデル、テクスチャモードなどがすべて追加されました。それぞれに独自の状態が必要です。単純な状態ベースのアプローチは、少数の状態があるときに機能しました。ステートが追加されるにつれて、APIは継ぎ目でバーストし始めました。APIはより厄介なものになりましたが、実際には多くの状態スイッチに基づいているため、ハードウェアモードからそれほど離れていません。

その後、プログラム可能なハードウェアが登場しました。ハードウェアはますますプログラム可能になり、現在では、ハードウェアが少しの状態、いくつかのユーザー提供のプログラム、および多くのバッファーをサポートしています。その時代のすべての固定機能機能がドライバーによってエミュレートされていたのと同じように、前の時代のそのすべての状態をエミュレートする必要がありました。

ハードウェアも、ますます並列化するように変更されました。これにより、グラフィックスの状態の変更を非常に高価にする他のハードウェアの再設計が必要になりました。ハードウェアは、不変状態の大きなブロックで動作します。これらの変更により、ドライバーは、ユーザーが設定した状態を少しずつ適用するだけではなく、変更を自動的にバッチ処理し、必要に応じて暗黙的に適用する必要がありました。

最新のハードウェアは、従来のOpenGLモデルからさらに機能します。DSAは、D3D10が行ったのと同様に、10年以上前に必要になった1つの小さな変更です(元々はOpenGL 3.0の一部として約束されていました)。上記のハードウェア変更の多くは、OpenGLを適切に維持するためにDSAだけでは足りませんそのため、OpenGLモデルを大幅に変更するさらに大きな拡張機能を利用できます。次に、まったく新しいGLnext APIに加えて、D3D12、Mantle、Metalなどがあり、時代遅れのステートマシンの抽象化を維持するものは1つだけではありません。


答えてくれてありがとう。したがって、ある時点ではステートマシン(非DSA)が勝利したように見えますが、ある時点で何かが変更され、DSAが有利になっています。何が変わったのかについて少し教えていただけますか?
Kromster 2015

@KromStern:頑張った。詳細が必要な場合は、私より詳しい知識のある人が提供する必要があります。
Sean Middleditch、2015

@KromStern私が見た(歴史の限られた研究から)openGLは、フレームあたりのCPUサイドの描画呼び出しがどんどん少なくなっています。表示リスト(それらの価値に応じて)、glDrawArrays(1回の呼び出しで描画)、VBO(GPUに1回アップロード)、VAO(バッファを属性に1回バインド)、ユニフォームバッファーオブジェクト(ユニフォームを一度に設定)。私が見逃していることがもっとあると確信しています。
ラチェットフリーク

@ratchetfreak:おかしなことに、私たちは今、逆の方向に進んでいます。最新のAPI /拡張機能は、フレームごとの描画呼び出しの増加に重点を置いています。主に、描画呼び出しごとに設定/ディスパッチする必要のあるすべての状態を削除し、大きなものに対して「コマンドをコマンドキューに描画コマンドを挿入する」以上の描画呼び出しを行わないようにします。静的状態とバインドレスリソースのセット。うーん、バインドレス、私は私の答えでその部分を言及するのを忘れていました。
Sean Middleditch、2015

@SeanMiddleditchフレームごとに呼び出しを設定する必要がありました。
ラチェットフリーク、

1

概要では、次のことを正当化します。

この拡張の目的は、ライブラリーがセレクターとラッチされた状態の妨げにならないように、ライブラリーをより効率的にすることです。この拡張機能では、セレクター更新コマンドの必要性をなくすことにより、コマンドをより効率的に使用することもできます。

ここで「より効率的」とは、ライブラリ作成者の簿記のオーバーヘッドを減らし、パフォーマンスを向上させることを指します。現在のAPIでは、「適切に動作する」ためには、状態を照会し、それを隠して、必要なことを行うように状態を変更してから、元の状態を復元する必要があります。

お気に入り

oldState = glGet()
glBind()
glDoThings...
glSet(oldState)  // restore, in case anyone needs it just as they left it

おそらく、明示的な状態変更APIを使用すると、古いハードウェアのパフォーマンスが向上する可能性があります。それ以外の場合はかなり奇妙な儀式です。この拡張は、フェッチ、セット、リストアダンスを回避することが、現在のハードウェアでのパフォーマンス向上につながることを意味します(そして、著者リストを参照してください!)。


「クエリ/スタッシュ/変更/復元が必要」-DSAの方が優れていますか?
Kromster 2015

..表示する擬似コードを追加。DSAでは、それは必要ありません。おそらく、現在のハードウェアは実際には「バインド」状態を必要とせず、必要に応じてすべてにアクセスできます。
david van brink 2015

get/bind/do/set「取得」が非常に遅いため、チェーンが使用されることはほとんどありません。通常、アプリはとにかく変数のレプリカを維持する必要があるため、に縮小されますbind/do。でも要点はわかります。
クロムスター、2015

2
@kromのドライバー状態からの取得は高速である可能性があります。一部のgettable状態はGPU上に存在しないため、高速なRAMから取得できます。
ラチェットフリーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.