2

イメージのロード/ストア操作を使用して imageBuffer で処理を実行する単一のフラグメント シェーダーがあります。私は次のシナリオについてのみ懸念しています。

  • 私は単一のフラグメント シェーダーを持っています (マルチステージ (例: 頂点シェーダーとフラグメント シェーダー) の考慮事項はなく、マルチパス レンダリングもありません)。
  • imageBuffer 変数はコヒーレントとして宣言されます。コヒーレントな imageBuffers にのみ関心があります。

物事を完全に明確にするために、私のシナリオは次のとおりです。

// Source code of my sole and unique fragment shader:
coherent layout(1x32) uniform uimageBuffer data;

void main()
{
  ...
  various calls to imageLoad(data, ..., ...);
  ...
  various calls to imageStore(data, ..., ...);
  ...
}

私は主に仕様を見てきました

ARB_shader_image_load_store

特にこの段落:

「「コヒーレント」として宣言された変数を使用すると、ストアの結果が、同様に宣言された変数を使用してシェーダー呼び出しにすぐに表示されることが保証されます。ストアが他の操作に確実に表示されるようにするには、MemoryBarrier を呼び出す必要があります。」

注:私の「一貫した均一なimageBufferデータ;」宣言は正確には「同様に宣言された」変数です。私のシナリオは、シングルパス、シングル ステージ (フラグメント シェーダー) です。

今、私はさまざまな Web サイトを見て、(私が思うほとんどの人のように) stackoverflow.com の次のスレッドに出くわしました。

GLSL の「コヒーレント」メモリ修飾子は、マルチパス レンダリングのために GPU ドライバによってどの程度正確に解釈されますか?

より具体的には、この段落:

「あなたのシェーダーは、ストアの直後にロードを発行すると、まさにこのシェーダーに保存されたばかりのメモリが取得されるという仮定さえできません (そうです。それを引き出すには、memoryBarrier を配置する必要があります)。」

私の質問は次のとおりです。

私の単一シェーダー、単一パス処理シナリオで指定されたコヒーレント修飾子を使用して、imageStore() がフラグメント シェーダーのすべての呼び出し (たとえば、現在の呼び出しも同様) にすぐに表示されることを確認できますか?他の同時呼び出しとして)?

ARB_shader_image_load_store 仕様を読むと、次のように思えます。

  • この質問への答えはイエスです。
  • 私はどんな種類のmemoryBarrier()も必要としません。
  • 上記のスタックオーバーフローのスレッドで引用された文は、実際には誤解を招き、間違っている可能性があります。

あなたの洞察に感謝します。

4

2 に答える 2

0

そのメモリバリアを使用してください。

たとえば、GPU はメモリのブロック全体を最適化およびフェッチして FROM を読み取り、TO に書き込む別のメモリを持っている場合があります。

つまり、シェーダーが常に単一の場所を一度だけ変更する場合は問題ありませんが、計算が適用された後に隣接値を中継する場合は、メモリバリアが必要です。

于 2014-05-22T08:38:48.787 に答える