glDrawElements
ドローターゲットをバックバッファとして呼び出してから呼び出すと、ドローさglReadPixels
れたものを読み取ることが保証されますか?
言い換えればglDrawElements
、ブロッキングコールですか?
glDrawElements
注:ここでは、ブロックされていないことが原因である可能性のある奇妙な問題を観察しています...
glDrawElements
ドローターゲットをバックバッファとして呼び出してから呼び出すと、ドローさglReadPixels
れたものを読み取ることが保証されますか?
言い換えればglDrawElements
、ブロッキングコールですか?
glDrawElements
注:ここでは、ブロックされていないことが原因である可能性のある奇妙な問題を観察しています...
言い換えれば、glDrawElementsはブロッキング呼び出しですか?
それはOpenGLがどのように機能するかではありません。
OpenGLメモリモデルは、「あたかも」ルールに基づいて構築されています。特定の例外は別として、OpenGLのすべては、発行したすべてのコマンドがすでに完了しているかのように機能します。実際には、すべてのコマンドが完了するまでブロックされているかのように機能します。
ただし、これは、OpenGL実装が実際にこのように機能することを意味するものではありません。それがそのように機能するように見せるために、それはただすべてをしなければなりません。
したがって、glDrawElements
通常はブロッキング呼び出しではありません。ただし、glReadPixels
(クライアントメモリに読み取る場合)はブロッキング呼び出しです。クライアントメモリへの直接のピクセル転送の結果は、glReadPixels
が戻ったときに利用可能である必要があるため、実装は、読み取られているフレームバッファに送信される未処理のレンダリングコマンドがあるかどうかを確認する必要があります。ある場合は、それらのレンダリングコマンドが完了するまでブロックする必要があります。次に、読み取りを実行して、データをクライアントメモリに保存できます。
バッファオブジェクトを読み取っている場合はglReadPixels
、ブロックする必要はありません。バッファオブジェクトを読み込んでいるため、クライアントがアクセスできるメモリは関数によって変更されません。したがって、ドライバーは非同期でリードバックを発行できます。ただし、このバッファの内容に依存するコマンドを発行する場合(読み取り用にマッピングしたり、を使用したりするなどglGetBufferSubData
)、OpenGL実装は読み取り操作が完了するまで停止する必要があります。
つまり、OpenGLはブロッキングを可能な限り遅らせようとします。パフォーマンスを確保するためのあなたの仕事は、絶対に必要でない限り、暗黙の同期を強制しないことによって、OpenGLがそうするのを助けることです。同期オブジェクトはこれに役立ちます。