10

私は現在、UBOを使用してOpenGL 4.3でレンダリングして、すべての定数データをGPUに保存しています。(マテリアルの説明、マトリックスなど...)。それは機能しますが、UBO のサイズが小さい (私の実装では 64kB) ため、バッファを何度も切り替える必要があり、レンダリングが遅くなります。数 MB を保存する同様の方法を探しています。

少し調査した結果、SSBO はそれを正確に許可するだけでなく、不要な「機能」も備えていることがわかりました。それらはシェーダーから書き込むことができ、読み取りが遅くなる可能性があります。

シェーダーに大量のデータを提供するための SSBO よりも優れたソリューションはありますか? もっと多くのデータを処理できるより柔軟なソリューションが存在するのに、UBO を数 kB に制限する必要があるのはなぜですか? シェーダー ストレージ バッファーが探しているものである場合、シェーダーによって変更されないようにする方法はありますか?

4

1 に答える 1

18

基本的に、UBO と SSBO は (通常は) 2 つの異なるハードウェアを表します1

シェーダーは、すべてのシェーダーがロックステップで実行されるように、グループで実行されます。個々のシェーダー呼び出しの各グループは、メモリ ブロックにアクセスできます。この記憶は、UBO が表すものです。比較的小さい (キロバイトのオーダー) ですが、アクセスは非常に高速です。レンダリング操作を実行すると、UBO からのデータがこのシェーダーのローカル メモリにコピーされます。

SSBO はグローバル メモリを表します。それらは基本的にポインターです。そのため、一般にストレージの制限はありません (最小 GL 要件は 16メガバイトであり、ほとんどの実装では GPU のメモリ サイズのオーダーで数値が返されます)。

アクセスは遅くなりますが、このパフォーマンスは、それらが一定ではない可能性があるためではなく、それらが存在する場所とアクセス方法によるものです。グローバル メモリは、ローカル定数メモリではなく、グローバル GPU メモリです。

シェーダーのローカル メモリに快適に収まるよりも多くのデータにシェーダーがアクセスする必要がある場合は、グローバル メモリを使用する必要があります。SSBO を「定数」と宣言する方法があったとしても、これを回避することはできません。

1 : 専用の UBO ストレージを持たないハードウェア (GCN ベースの AMD ハードウェア) が存在します。このハードウェアは UBO を単なる読み取り専用 SSBO として実装しているため、すべての UBO アクセスはグローバル メモリ アクセスです。このハードウェアは基本的に、パフォーマンスの違いを補うために大きなキャッシュを持つことに依存しており、UBO の使用パターンはこれを実行可能にする傾向があります。ただし、UBO ストレージ専用のスペースを備えたハードウェアはまだたくさんあるため、これらの制限内で使用できる場合は、それらを使用する必要があります。

于 2015-12-03T16:39:24.033 に答える