フラグメント シェーダーは、2 つのアトミック カウンターを使用します。最初の値をインクリメントする場合としない場合と、2 番目の値をインクリメントする場合としない場合があります (ただし、両方をインクリメントすることはありません)。ただし、カウンターを変更する前に、現在の値が常に読み取られ、カウンターが後で変更された場合、以前に読み取られた値がカスタム ロジックに使用されます。これはすべて (ほとんどの場合展開可能な) ループで発生します。
大まかに次のようなフローを想像してください。
- FOR 0-20(コンパイル時に解決可能なconst)など、いくつかの小さな展開可能なループで...
- AC1 と AC2 のカウンター値を取得する
- いくつかの値を確認してください:
- x の場合: uimage1D_A のテクセルをインデックス AC1 に設定し、AC1 をインクリメントします。
- それ以外: uimage1D_B のインデックス (imgwidth-AC2-1) にテクセルを設定し、AC2 をインクリメントします。
質問: シェーダーは現在のカウンター値を照会します。常に「最新」の値を取得しますか? ここで、フラグメント シェーダーの大規模な並列性が失われますか (現在の世代および将来の GPU とドライバーに関してのみ)?
分岐 (if x) については、別の ( readonly restrict uniform
)のテクセルをuimage1D
( uniform
)と比較しuint
ます。したがって、一方のオペランドは間違いなく均一なスカラーですが、もう一方はimageLoad().x
画像は均一ですが、この種の分岐はまだ「完全に並列化」されていますか? 両方の分岐がそれぞれ正確に 2 つのほぼ同一の命令であることがわかります。「完全に最適化された」GLSL コンパイラを想定すると、この種の分岐はストールを引き起こす可能性がありますか?