次のパイプラインがあります。
- カスタム FBO へのテクスチャ アタッチメントにレンダリングします。
- そのテクスチャ アタッチメントをイメージとしてバインドします。
- imageLoad/Store を使用して、上記の画像からコンピューティング シェーダー サンプリングを実行します。
- 結果を SSBO またはイメージに書き込みます。
- SSBO (または画像) を CUDA CUgraphicsResourceとしてマップし、CUDAを使用してそのバッファーからのデータを処理します。
さて、問題はステージ 4 と 5 の間のデータの同期にあります。私が試した同期ソリューションは次のとおりです。
glFlush - すべてのコマンドの実行の完全性を保証しないため、実際には機能しません。
glFinish - これは機能します。ただし、ドライバーに送信されたすべてのコマンドをファイナライズするため、お勧めしません。
ARB_sync ここでは、パフォーマンスに大きく影響するため、推奨されないと言われています。
glMemoryBarrierこれは興味深いものです。しかし、それは単に機能しません。
コードの例を次に示します。
glMemoryBarrier(GL_ALL_BARRIER_BITS);
また、試しました:
glTextureBarrierNV()
コードの実行は次のようになります。
//rendered into the fbo...
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindImageTexture(imageUnit1, fboTex, 0, GL_FALSE, 0, GL_READ_ONLY,GL_RGBA8);
glBindImageTexture(imageUnit2, imageTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8));
glDispatchCompute(16, 16, 1);
glFinish(); // <-- must sync here,otherwise cuda buffer doesn't receive all the data
//cuda maps the image to CUDA buffer here..
さらに、計算を起動する前にコンテキストから FBO とテクスチャのバインドを解除しようとしglMemoryBarrierました。それらの間にセットを置いて次々と計算を起動し、最初の計算起動からターゲット イメージを CUDA にフェッチすることさえ試みました。まだ同期していません。(まあ、2 つの計算が互いに同期していないので、これは理にかなっています)
計算シェーダー段階の後。同期しない!glFinish、またはパイプラインを完全に失速させる他の操作に置き換えた場合のみ。glMapBuffer()たとえば、のように。
それでは、glFinish() を使用する必要がありますか、それともここに何かが欠けていますか? CUDA が制御を引き継ぐ前に glMemoryBarrier() が計算シェーダーの動作を同期しないのはなぜですか?
アップデート
元の質問がかなり古いので、質問を少しリファクタリングしたいと思います。それにもかかわらず、最新の CUDA および Video Codec SDK (NVENC) を使用しても問題は解決していglMemoryBarrierません。したがって、同期しない理由は気にしません。私が知りたいのは:
レンダリング パイプライン全体 (私の場合は OpenGL イメージ) を停止することなく、OpenGL コンピューティング シェーダーの実行を CUDA の共有リソースの使用と同期させることができる場合。
答えが「はい」の場合、どのように?