4

この基準は、最初のコマンドからレンダリングを開始し、それ以降のglコマンドと並行して継続することをほのめかしています。glBufferSubDataオブジェクトが現在使用されていない限り、レンダリング中に読み込みが発生する可能性があることを示すなどの特定の機能。これにより、「フレーム」の論理的な概念が導入されますが、標準では明示的に言及されていません。

私の質問は、この論理フレームを定義するものは何ですか? つまりgl、前のフレームに干渉することなく再び呼び出しを開始できるように、どの呼び出しがゲームの境界を定めるのでしょうか?

たとえば、EGL を使用して最終的に呼び出しますeglSwapBuffers(ほとんどの実装には、ある種の swap コマンドがあります)。論理的には、これは 1 つのフレームと次のフレームの間の境界です。ただし、これはブロックを呼び出して v-sync をサポートするため、返されるまで新しいコマンドを発行できません。それでも、ドキュメントは、別のスレッドで戻る前に新しいコマンドの発行を開始できることを暗示しています (使用中のバッファーに触れない場合)。

swap コマンドがまだ前のバッファでブロックしている場合でも、次のバッファへのコマンドの発行を開始するにはどうすればよいですか? GPU が古いフレームで作業している間に、次のフレームのデータのストリーミングを開始したいと思います (特に、この目的のためにフレームごとにスワップされる 2 つの頂点バッファーがあり、OpenGL のドキュメントで言及されています)。

4

1 に答える 1

12

OpenGL には、論理的であろうとなかろうと、「フレーム」という概念がありません。

OpenGL は非常に単純です。すべてのコマンドは、前のすべてのコマンドが事前に完了しているかのように実行されます。

「あたかも」というキーワードに注意してください。バッファ オブジェクトからレンダリングし、その後すぐにそのデータを変更するとします。このような:

glBindVertexArray(someVaoThatUsesBufferX);
glDrawArrays(...);
glBindBuffer(GL_ARRAY_BUFFER, BufferX);
glBufferSubData(GL_ARRAY_BUFFER, ...);

これは、OpenGL では 100% 合法です。これがどのように機能するかについて、警告、質問、懸念などはありません。そのglBufferSubData呼び出しは、glDrawArraysコマンドが終了したかのように実行されます。

考慮しなければならない唯一のことは、仕様で指定されていない唯一のことです:パフォーマンス.

実装は、使用中の可能性のあるバッファーを変更していることを検出する権利を十分に持っているため、glBufferSubDataそのバッファーからのレンダリングが完了するまで CPU をストールさせます。OpenGL の実装では、これを行うか、実際のソース バッファが使用中に変更されないようにするその他のことを行う必要があります

そのため、OpenGL の実装は、仕様に従って、可能な場合は非同期でコマンドを実行します。外の世界がglDrawArrays何も描画を終えていないことを認識できない限り、実装はそれが望むことを何でも行うことができます。glReadPixels描画コマンドの直後に発行すると、パイプラインは停止する必要があります。実行できますが、パフォーマンスを保証するものではありません。

これが、OpenGL が閉じたボックスとして定義されている理由です。これにより、実装は可能な限り非同期にする自由度が高くなります。OpenGL データへのすべてのアクセスには、OpenGL 関数呼び出しが必要です。これにより、実装は、そのデータがまだ実際に利用可能かどうかを確認できます。そうでない場合は、失速します。

バッファ オブジェクトの無効化が可能な理由の 1 つは、ストールを取り除くことです。バッファのデータストレージを孤立させたいことをOpenGLに効果的に伝えます。これが、バッファ オブジェクトをピクセル転送に使用できる理由です。これにより、転送を非同期で行うことができます。これがフェンス同期オブジェクトが存在する理由であり、リソースがまだ使用されているかどうかを知ることができます (おそらくGL_UNSYNCHRONIZED_BITバッファー マッピング用)。などなど。

ただし、これはブロックを呼び出して v-sync をサポートするため、返されるまで新しいコマンドを発行できません。

誰が言ったのですか?バッファ スワッピング コマンド停止する場合があります。そうではないかもしれません。これは実装定義であり、特定のコマンドで変更できます。のドキュメントにeglSwapBuffersは、フラッシュを実行するとのみ記載されています。これにより、CPU が停止する可能性がありますが、そうする必要はありません。

于 2012-08-20T09:05:18.307 に答える