ゲーム内グラフィカル プロファイラー (CPU および GPU) を作成しましたが、Nvidia ドライバーで奇妙な動作が 1 つあります。
通常の場合のスクリーンショットを次に示し
ます。ここに表示されているのは、3 つの連続したフレームで、上部が GPU、下部が CPU です。両方のグラフが同期されます。
「END FRAME」バーには、への呼び出しのみが含まれますSwapBuffers。GPU がすべての作業を完了するまでブロックしているのは奇妙に思えるかもしれませんが、vsync がオンで、すべての作業 (CPU と GPU) が 16ms に収まる場合にドライバーが選択することがあります (AMD も同じです)。私の推測では、入力の遅れを最小限に抑えるためにそれを行うということです。
今私の問題は、それが常にそうであるとは限らないということです。フレーム内で何が起こるかによって、グラフは次のようになることがあります:
ここで実際に起こることは、SwapBuffers. この特定のケースでは、ブロッキング コールはglBufferData. それを行うダミーコードを追加すると、はるかに目立ちます(均一なバッファを作成し、ランダムな値をロードして破棄します):

これは、明らかな理由もなくグラフのバーが非常に大きくなる可能性があることを意味するため、問題です。これを見た人は、一部のコードが遅いという誤った結論を導き出す可能性があります。
私の質問は、このケースをどのように処理できますか? 意味のある CPU タイミングを常に表示する方法が必要です。
ユニフォーム バッファをロードするダミー コードを追加するのはあまり洗練されておらず、ドライバーの将来のバージョンでは機能しない可能性があります (ドライバーが代わりにドローコールのみをブロックするとしたらどうなるでしょうか?)。
フレームレートが低下すると、ドライバーはブロックを停止してCPUとGPUフレームを並行してglClientWaitSync実行できるようにするため、呼び出しを停止するにはそれを検出する必要があるためですglClientWaitSync(ただし、どうすればよいかわかりません。)
(より良いタイトルの提案は大歓迎です。)
編集: GPU がボトルネックである場合、vsync なしで何が起こるか:
GPU フレームは CPU フレームよりも時間がかかるため、ドライバーglBufferDataは GPU が追いつくまで CPU をブロックすることにしました。
条件は同じではありませんが、問題は、ドライバーが OpenGL 関数ブロックの一部を作成するため、CPU タイミングが「間違っている」ことです。これは実際には、vsync をオンにしたものよりも理解しやすい例かもしれません。