1

PBO を使用して CPU と GPU の間でデータを転送する GPGPU アプリケーションに取り組んでいます。私のアプリケーションの要件の 1 つは、OpenGL レンダリング スレッドのブロックをできるだけ少なくし、処理のレイテンシをできるだけ低くすることです。

私の質問は、glTexSubImage2D への呼び出し (ホストからデバイスへの変換を開始する) と実際にテクスチャを使用/レンダリングする間にレイテンシを追加する必要があるかどうかです。たとえば、サイズが 1024x1024 のテクスチャの場合、そのようなレイテンシはどれくらいの大きさでなければなりませんか?

for(auto texture: textures)
{
    glBindTexture(GL_TEXTURE_2D, texture.id());
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, ...);
    glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, ..., NULL, GL_STREAM_DRAW);
    void* mem = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
    copy(mem, data);
    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
    glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, ..., NULL);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
}

do_other_cpu_stuff_while_data_is_transferring(); // Is this needed to avoid blocking calls while rendering? If so, what strategy can I use to estimate the minimum amount of time needed to transfer the data.

for(auto texture: textures)
{
    render(texture);
}
4

2 に答える 2

3

ほとんどのレイテンシーは copy() および/または glUnmapBuffer() の呼び出しにあると言えますが、それは非常に多くのこと (主にハードウェア) に依存するため、最善の策は、最初に 1 つの転送を行うことです。プログラムとそれらを測定します。タイミングについては、glFinish() 関数を高解像度タイマー (QuerPerformanceCounter など) と共に使用する必要があります。

于 2011-07-31T19:11:49.820 に答える
1

これは構造化されているため、ブロックされる可能性がありますglTexSubImage(最終的には実装に依存しますが、理論的には実装これを延期する可能性があります)。glTexSubImage最初にいくつかのバッファーをアップロードしてから、それらが定義/アップロードされた順序でそれぞれを呼び出した場合、ストールが大幅に少なくなる可能性があります。

このdo_other_cpu_stuff呼び出しは、すでにブロックされているため、あまり役に立たない可能性があります。

ARB_copy_buffer 機能を利用できる場合は、最初に一時バッファーにいくつかのバッファー データを定義し、次に GPU でバッファーからバッファーへのコピーを行うように OpenGL に指示することで、ストールをさらに回避できます。
直感的には、これは速くない (むしろ遅い) はずですが、何らかの理由で私にはわかりませんが、実際には高速です。

于 2011-07-31T21:55:50.197 に答える