2

次のシナリオがあります。

カラーアタッチメントとしてテクスチャを使用したカスタムFBOがあります。そのFBOにコンテンツをレンダリングします。次のステップでは、そのテクスチャをCUDAと共有し、後処理カーネルで実行する必要があります。その後、テクスチャをフルスクリーンにバインドする必要があります。クワッドで、デフォルトのフレームバッファにレンダリングされます。私はいくつかのOpenGL/CUDA相互運用​​チュートリアルを読みましたが、これを行うためのいくつかのステップは私には完全には明確ではありません。

まず、彼らが通常行うことは、GLテクスチャXからデータを読み取り、それをCUDAで処理してから、PBO塗りつぶしテクスチャYを使用して結果のデータを取得することです。

私が気付いたもう1つのこと(間違っている場合は訂正してください)は、これらのデモのOpenGLがデフォルトでバインドされたPBOを使用していることです。つまり、最初のパスのレンダリング結果がそこに保存されますか?これらのデモはすべて固定のOpenGLを使用しており、最初のジオメトリパスがレンダリングされたときにPBOがバインドされる場所がないため、私はそれについて本当に確信が持てません。

さて、私の場合に戻りましょう。最後の質問は、PBOを使用せずにCUDAのOpenGLテクスチャを直接操作して、CUDAカーネルで変更できるようにすることはできますか?いいえの場合、それはCUDAステージに渡す前にFBOテクスチャをPBOにパックする必要があることを意味しますか?

アップデート:

フレームバッファからのPBOの入力は、通常glReadPixels()を使用して実行されます。これは、CPUにダウンロードされることを意味します。これは防止したいことです。-それは間違った仮定でした。それで、テクスチャからのピクセルでPBOを埋めることができるという事実に基づいて、次の方法がありますか?:PBOにテクスチャからのデータを入力します。

それをCUDAバッファーリソースにマップします。

カーネルを使用してデータに変更を加えます。

変更されたPBOからターゲットテクスチャを更新します。

OpenGLで更新されたテクスチャを使用します。

4

2 に答える 2

1

フレームバッファからのPBOの入力は、通常glReadPixels()を使用して実行されます。これは、CPUにダウンロードされることを意味します。これは防止したいことです。

間違い!

PBOへのglReadPixelsは完全にGPUで実行され、システムメモリへのラウンドトリップは行いません。

アップデート:

CUDA-グラフィックスの相互運用にはいくつかの制約があります。たとえば、グラフィックスコンテキストでバインドされている間は、グラフィックスリソースをCUDAメモリにマップすることはできません。具体的にはマップできますが、アクセスすると未定義の結果が生成されます。したがって、通常の戦略ではプロキシオブジェクトを使用します。

したがって、OpenGLからCUDAへの仲介としてPBOを使用することは、問題のOpenGLリソースが何らかの理由でバインド解除できない場合に価値のある方法です。ただし、FBOの場合は、FBOにバインドされているものはすべて、バインドされている限りデータソースとして使用できないため、実際には問題になりません。その制限により、通常、ターゲットオブジェクト(レンダーバッファまたはテクスチャ)のインスタンスがいくつか存在し、マルチバッファ方式でラウンドロビンを使用します。

したがって、コピーするか、CUDAにマッピングする前にバインドを解除します。複数のバッファを使用する場合は、後者が推奨される方法です。

CUDAテクスチャを使用する場合は、読み取り時に常に別のテクスチャに書き込む必要があります(テクスチャの場合は、CUDAサーフェスにバインドする必要があります)。

于 2013-02-24T17:08:39.020 に答える
1

CUDAで「OpenGLテクスチャ」を処理し、追加のオーバーヘッドなしでOpenGLですぐに使用する例を次に示します。

https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st

于 2015-05-12T18:16:09.447 に答える