1

したがって、例とチュートリアルを見てみると、パイプラインにバッファを配置する最も一般的な方法は、すべてのモデルオブジェクトが独自の頂点バッファを取得し、バッファがいっぱいになった後、ロック、バッファの設定、ロック解除、設定を行うことです。シェーダー、描画、およびすべてのモデルの個々のバッファーのリンス/リピート。すべてのロックとロック解除は物事を少し遅くするだろうと私には思えます。

したがって、モデルオブジェクトが代わりにすべての頂点を1つの大きな配列に集約し、すべてのインデックスを大きな配列に集約し、1つの大きなバッファーを作成し、1回ロックし、バッファーを1回設定し、ロックを解除してから、シェーダーを切り替えて描画できるかどうか疑問に思います。これらのシェーダーで必要な数のポリゴンを作成し、描画する前に毎回パイプラインでより多くの頂点をロックしてドロップする必要がなく、以前のようにバッファーの描画とシェーダーの切り替えに沿って作業します。

これはもっと効率的でしょうか、それとも、関連するすべての簿記からのオーバーヘッド(たとえば、インデックスaからインデックスbまで、このシェーダーを使用する)によって、これが価値以上に機能するようになると思いますか?

また、ここでd3dの概念を見逃した場合は、お知らせください。(私は新しいです)

編集

大きな誤解のために、私がロックとロック解除について言及したところはどこでも、実際にはIASetVertexBuffer/IASetIndexBufferを呼び出すだけであるはずでした。「改訂された」質問は多かれ少なかれ次のとおりです。

シーン内のすべてのモデルの頂点を1つの単一のバッファーに詰め込み、IASetVertexBufferを1回呼び出すだけで、パフォーマンスがまったく向上しますか?

4

2 に答える 2

3

だから、例やチュートリアルを見回してから

止まる。ほとんどの「例とチュートリアル」は、ベストパフォーマンスプラクティスを示すことを目的としたものではありません。特にベストパフォーマンスプラクティスに関するものでない限り。彼らは、タスクXを実行する方法を最も明確かつクリーンな方法で示しようとしています。最適化はまったく別の問題です。最適化されたコードは、最適化されていないコードよりも明確でクリーンではありません。したがって、多くの最適化は、チュートリアルで述べられている目的の邪魔になります。

したがって、チュートリアル何らかの方法でそれを行うという理由だけで、それが何かを行うための最速の方法であると思い込まないでください。それは単にそれを行うための1つの方法です。

次に、バッファーがいっぱいになると、すべてのモデルの個々のバッファーに対して、ロック、バッファーの設定、ロック解除、シェーダーの設定、描画、およびリンス/リピートが行われます。

ロックとロック解除は、バッファを変更するためのものです。あなたがそれを変更していないのなら...なぜあなたはそれをロックしているのですか?また、変更する場合は、何らかの形式のバッファストリーミングを実行します。これには、効率を上げるために特別な処理が必要です。

ストリーミングを行っている場合、それはあなたが尋ねるべき別の質問です(つまり、高性能の頂点ストリーミングを行う方法)。

それは、複数のオブジェクトのデータを1つのバッファーに入れることが良い考えではないということではありません。しかし、そうであれば、その理由は、ロックとロック解除とは関係がなく、1回の描画呼び出しで複数のオブジェクトを描画する可能性と関係があります。

于 2012-04-19T16:21:29.200 に答える
1

一般に、ロックが少ないほど良いのですが、すべてのロックは、GPUをストールさせるシステムメモリとグラフィックカードメモリ間の同期転送である必要があります。これらの転送をまとめてバッチ処理できるほど、優れています。

ただし、さらに優れた改善点は、単独で変更されないバッファーを残すことです。ベンチ#1221を毎回リロードする必要はありません。独身。フレーム。変更されることはありません(*)。したがって、最初に静的アートをロードし、必要に応じて描画します。また、前処理でベンチの半分をカリングすることを考える前に、GPUが電光石火の速度で基本的なカリングを行う方法をすでに知っている場合に、いくつかの頂点を取り除くためだけにバッファーをロックするコストについてよく考えてください。

(*)もちろん変わらないと仮定して:)

于 2012-04-19T16:21:04.787 に答える