Vulkan:静的データの均一バッファーとプッシュ定数


8

均一バッファーとプッシュ定数の概念的な違いを理解するのに苦労しています。仕様を読んで集めることができるものと、主な違いは次のとおりです。

  1. 均一バッファーは、プッシュ定数よりもはるかに大きくなる可能性があります。
  2. UBOはstd140を使用し、PCはstd430を使用します。
  3. UBOはvkCmdUpdateBuffer(またはホストマッピング)を使用していつでも更新でき、その値を保持できます。それ以外の場合は、レンダーパスごとにPCを再プッシュする必要があります。(私を驚かせた-名前に基づいて。パイプラインの定数をそのまま更新し、それらの変更を持続させると思った)

私のシナリオでは、約200バイト相当のデータがあり、ほぼ一定であると予想しています。つまり、それらを非常にまれに変更します。すべてのコマンドバッファーでプッシュ定数を再送信する必要がある場合でも、(サイズが許す限り)プッシュ定数を使用する方が良いでしょうか?または、200バイトのUBOを使用して、vkCmdUpdatebufferでたまにしか更新しない方がよいでしょうか?

また。たとえばfloat random_seed、シェーダーが実行されるたびに更新するaがある場合はどうなりますか?私がすでにUBOを持っていると仮定すると、UBOの残りが一定であっても、UBOで一括処理する方が良いでしょうか、またはこの変数にプッシュ定数を使用することで利益を得られるので、すべてのレンダーパスの前にvkCmdUpdateBuffer?


Computer Graphics Stack Exchangeサイトへようこそ!私はVulkanに精通していませんが、あなたの場合はUBOを使用する方が効率的です(サンプルプログラムで両方のアプローチのパフォーマンスを比較してみてください)。知っているグラフィックAPIはどれですか。また、このGDC 2012のプレゼンテーションに興味があるかもしれません。すべてを捨てないでください:効率的なバッファー管理
wip

Vulkanのドキュメントから:UBOがGPUでビデオメモリのブロックを割り当てている間(後で更新できます)、プッシュ定数はビデオメモリを使用しません(そのため、描画/計算呼び出しのたびに提供する必要があります。そうしないと、シェーダーは使用する値を認識しません)。詳細はGPUベンダーによって異なる場合がありますが、GPU上の他の短期の高速ストレージ領域に格納されていると思います。
wip

回答:


8

UBOはvkCmdUpdateBufferでいつでも更新できます

仕様から:「vkCmdUpdateBufferはレンダーパスの外でのみ許可されます。」したがって、「いつでも」はそうではありません。

レンダーパスの内部で許可されていても、転送操作です。つまり、メモリ転送をそれを使用するコマンドと同期させる必要があります。パフォーマンスが低下します。

一般的なプッシュ定数と均一のことについては、あなたの判断を使用してください。「判断」とは、それらがどのように機能するかを見るだけです。プッシュ定数を使用すると、メモリ操作、同期、記述子の状態の変更などの重いプロセスを実行せずに、いつでもデータを変更できます。明らかに、これらは頻繁に変更されるデータ用です。どのくらいの頻度で「頻繁に」ですか?まあ、それは裁判の呼び出しです。

それができない場合は、パフォーマンスの違いをプロファイルしてください。


2

約200バイト相当のデータがあり、ほぼ一定であると期待しています。つまり、それらを非常にまれに変更します。

データが頻繁に変更されない場合は、特殊化定数を使用できます。それらはパイプラインの作成時に設定され、値を変更する必要がある場合は新しいパイプラインを作成する必要があります。ウィンドウのサイズ変更などのまれなイベントの場合、これは許容できるコストになる可能性があります。

たとえば、シェーダーが実行されるたびに更新するfloat random_seedがある場合はどうなりますか?

これは、プッシュ定数の完全なユースケースです。他のすべてのデータをUBO(または特殊化定数)に保持し、この値をで変更できますVkCmdPushConstants

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.