2

ウィキペディアや他の情報源によるOpenGL4.0の説明で、私はこの機能について読みました。

CPUの介入なしに、OpenGLまたはOpenCLなどの外部APIによって生成されたデータの描画。

これは何を指しているのですか?

編集

このように見えるのは、Draw_Indirectを参照している必要があります。これは、シェーダープログラムまたは相互運用機能からのプログラム(基本的にはOpenCL / CUDA)からのフィードバックを含むように描画フェーズを拡張すると思います。 2回目の実行を過ぎてもGPUで長時間使用できますが、可能であるはずです。

CPUなしで描画コマンドを使用する方法についてさらに情報を提供できる場合、または描画間接をより適切に説明できる場合は、遠慮なくそうしてください。よろしくお願いします。

4

3 に答える 3

3

OpenGLがGPUバッファオブジェクトからDrawArraysまたはDrawElementsパラメータを取得できるようにするGL_ARB_draw_indirect機能を参照している可能性があります。これは、OpenGLまたはOpenCLで埋めることができます。

私が間違っていなければ、それはコアOpenGL4に含まれています。

于 2011-02-19T01:36:18.250 に答える
2

私が理解している限り、OpenGL 4.0は以前から存在していたため、この機能がどのように機能するのか特にわかりません。これがあなたの質問に答えるかどうかはわかりませんが、とにかくその主題について私が知っていることを教えます。

これは、OpenCLやCUDAなどのOpenGL以外のライブラリがグラフィックカードのメモリに直接データを生成し、OpenGLが他のライブラリが残った場所から続行し、そのデータを次のように使用する状況を指します。

  • データをそのまま画面に描画したい場合のピクセルバッファオブジェクト(PBO)
  • グラフィックデータを他のシーンの一部として使用したい場合のテクスチャ
  • 生成されたデータを頂点シェーダーの任意の属性入力として使用する場合の頂点バッファーオブジェクト(VBO)。(この一例は、CUDAでシミュレートされ、OpenGLでレンダリングされるパーティクルシステムです)

このような状況では、データを常にグラフィックカードに保持し、コピーしないことをお勧めします。特に、CPUを介してデータをコピーしないでください。これは、PCIeバスがグラフィックスカード。

VBOおよびPBO用のCUDAおよびOpenGLでトリックを実行するためのサンプルコードを次に示します。

// in the beginning
glGenBuffers(&id, 1);

// for every frame
cudaGLRegisterBufferObject(id);
CUdeviceptr ptr;
cudaGLMapBufferObject(&ptr, id);
// <launch kernel here>
cudaGLUnmapBufferObject(id);
// <now use the buffer "id" with OpenGL>
cudaGLUnregisterBufferObject(id);

そして、データをテクスチャにロードする方法は次のとおりです。

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, id);
glBindTexture(GL_TEXTURE_2D, your_tex_id);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, 0);

また、GL_RGBAの代わりにもっと変わった形式を使用すると、すべての値を変換する必要があるため、処理が遅くなる可能性があることにも注意してください。

OpenCLはわかりませんが、考え方は同じです。関数名のみが異なります。

同じことを行う別の方法は、いわゆるホスト固定メモリです。このアプローチでは、CPUメモリアドレス範囲の一部をグラフィックカードメモリにマップします。

于 2011-02-18T23:57:47.983 に答える
0

この機能が何であるかを理解するには、以前に物事がどのように機能したかを理解する必要があります。

4.0より前では、OpenCLはOpenGLバッファオブジェクトをデータで埋めることができました。実際、通常のOpenGLコマンドは、変換フィードバックを使用するか、バッファテクスチャにレンダリングすることにより、OpenGLバッファオブジェクトをデータで埋めることができます。このデータは、レンダリングに使用される頂点データである可能性があります。

頂点データのレンダリングを開始できるのはCPUだけです(glDraw*関数の1つを呼び出すことによって。それでも、ここで明示的な同期を行う必要はありません(OpenCL / OpenGL相互運用機能が必要とするものを除く)。具体的には、CPUにはありません。GPU操作によって書き込まれたデータを読み取るため。

しかし、これは問題につながります。OpenCLまたはその他のGPU操作が常に既知の数の頂点をバッファーに書き込む場合、すべてが正常です。ただし、これが当てはまる必要はありません。GPUプロセスでは、任意の数の頂点を書き込むことが望ましい場合がよくあります。明らかに、最大制限(バッファのサイズ)が必要です。しかしそれ以外は、好きなように書けるようにしたいと思います。

問題は、OpenCLが書き込む数を決定したことです。ただし、CPUは、関数の1つを使用するために、その番号を必要としglDrawます。OpenCLが22,000の頂点を書き込んだ場合、CPUは22,000をに渡す必要がありますglDrawArrays

ARB_draw_indirect (GL 4.0のコア機能)が行うことは、GPUプロセスが関数に渡すパラメーターを表す値をバッファーオブジェクトに書き込むことを可能にすることですglDraw*。これでカバーされない唯一のパラメータはプリミティブ型です。

CPUは、レンダリングがいつ行われるかを引き続き制御することに注意してください。CPUは、頂点データを取得するバッファを決定します。したがって、OpenCLはこれらのglDraw*コマンドのいくつかを書き込むことができますが、CPUが実際glDrawElementsIndirectにそれらのいずれかを呼び出すまで、実際には何もレンダリングされません。

したがって、実行できるのは、既存のバッファーオブジェクトにデータを書き込むOpenCLプロセスを実行することです。次に、VAOのように、通常の頂点設定を使用してこれらのバッファーをバインドします。OpenCLプロセスは、適切なレンダリングコマンドデータを他のバッファーオブジェクトに書き込み、間接バッファーとしてバインドします。次に、を使用glDraw*Indirectしてこれらのコマンドをレンダリングします。

CPUがGPUからデータを読み戻す必要はありません。

于 2012-03-17T07:35:20.823 に答える