ffmpeg でピクセルをデコードして rgb8 形式に変換し、マップされたピクセル バッファーに書き込み、ストリーミングを使用して opengl テクスチャを更新し、それを sdl ウィンドウにレンダリングしようとしていました。
デコードとアップロードは専用スレッド (make sws_scale がマップされたバッファーに書き込む) で行われ、レンダリングは共有を伴う別のコンテキストのレンダリング スレッドで行われます。(PBO は実際には複数のフレームを保持し、テクスチャは位置を切り離すために 2D 配列テクスチャです。)
デコード スレッドでマップされた範囲をフラッシュし、レンダリング スレッドで glTextureSubImage3D を使用して、必要なインデックスでテクスチャを更新すると、問題なく動作します。このシナリオでは、統合された Intel GPU はかなり高速に動作します (そうあるべきです) が、NV ドライバーは次のように文句を言います。Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering.
glTextureSubImage3D だけが実際にアップロードを行うのではないかと考えたので、フラッシュ操作の直後に glTextureSubImage3D を移動しました。今回は、NV GPU は正常に動作し、警告は消えますが、Intel GPU では黒いウィンドウが表示され、閉じるときにデコードされたコンテンツのみが表示されます。
コードは次のようなものです。
//render thread
void RenderFrame(SDL_Window* window,GLobjects& glo, int index, int width, int height) {
glUniform1f(glo.index_location,index);
//The function in question
glTextureSubImage3D(glo.texture, 0, 0, 0, index, width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)(index * width * height * 4));
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
SDL_GL_SwapWindow(window);
}
//Decode thread
int DecodeFrameToPBO(GLobjects& glo, int index){
//fill the mapped range needed
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, index * width * height * 4, 4 * width * height);
//The function in question
//glTextureSubImage3D(glo.texture, 0, 0, 0, index, width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)(index * width * height * 4));
}
クライアント側のメモリのアイデアと、ドライバーがテクスチャを非同期にアップロードする方法、アップロードが行われる正確な場所、および GL_PIXEL_UNPACK_BUFFER がバインドされているときに glTextureSubImage3D が実際に行うことについて、私は本当に混乱していますか?
編集:
各アップロード後にアップロード コンテキストのコマンド キューをフラッシュする glFlush() コマンドを追加した後、Intel バージョンはブラック スクリーンなしで適切に動作します。
アップデート:
glFlush() を追加すると、NV GPU が「ピクセル パス パフォーマンスの警告: ピクセル転送が 3D レンダリングと同期されます」という警告を発するようです。再び、同じビデオ サンプルの GPU 使用率が 8% から 10% に増加しました。glFlush() が何らかの内部同期をトリガーしているようで、おそらく物事がビジー待機状態になりますか? Intel GPU は glFlush なしでは動作しないため、クライアント待機同期バージョンで flush コマンド ビットが設定されていても、レンダリング側で明示的に flush を呼び出しても動作しません。では、両方のドライバーを満足させる (そして使用率を下げる) にはどうすればよいでしょうか?