web-dev-qa-db-ja.com

GL_STREAM_DRAWまたはGL_DYNAMIC_DRAWを選択する方法は?

私はOpenGL ES 2.0を使用していますが、ES以外にも関係があると思います。VBOを作成するときに選択する「使用法」を知る方法は?

この特定のVBOは、完全に更新される前に1〜4回使用されるため、GL_STREAM_DRAWまたはGL_DYNAMIC_DRAWを選択する必要があるかどうかはわかりません。

28
lvella

OpenGL API によると、DYNAMIC_DRAWを使用する必要があります。

[〜#〜]ストリーム[〜#〜]
データストアのコンテンツが1回変更され、最大で数回使用される場合は、STREAM_DRAWを使用する必要があります。

[〜#〜]静的[〜#〜]
データストアの内容が1回変更され、何度も使用される場合は、STATIC_DRAWを使用します。

[〜#〜]動的[〜#〜]
データストアの内容が繰り返し変更され、何度も使用される場合は、DYNAMIC_DRAWを使用します。

VBOを必ず glBufferSubData() で更新してください

21
murk003

使用フラグはヒントではなく、強制ではありません。または言い換えると、「間違った」フラグを使用しても問題は解決しません。したがって、STATIC_DRAW、STREAM_DRAW、DYNAMIC_DRAWの3つすべてを試して、最高のパフォーマンスが得られるものを選択することをお勧めします。

11
datenwolf

これまでの回答に加えて、GLESとは直接の関係はありませんが、 ARB_buffer_storage 拡張機能の第2号からこのビットを貼り付けたいと思います(デスクトップと共に導入GL 4.4):

2)新しいフラグは、glBufferDataのパラメーターに直接マップされず、一方を他方に関して表現することはできません。それは重要ですか?

ほとんどのアプリケーションはusageを間違って取得し、とにかくヒントにすぎません。フラグは従わなければならない厳格なルールです。彼らは別の目的を果たします。ここでの考え方は、実装がアプリケーションを2番目に推測する必要がなく、追跡を少なくすること、およびアプリケーションがより多くの制御を行えるようにすることです。私たちは、最も寛大なフラグ(本質的には何でも)を使用して、BufferStorageの観点からBufferDataを定義しますが、ヒントを実装に渡して、アプリケーションが2番目に推測し続けることを許可します。

これらのフラグの問題は常に、使用方法のヒントが示すさまざまなパスを最適化する方法について、実装ごとに異なるアイデアがあり、アプリケーションごとにこれらの最適化がどのように機能するかについて期待が異なるように見えることです。

NvidiasデスクトップGLドライバーは、デバッグプロファイルで、特にそれらがクライアントに保存されている場合、バッファオブジェクトに対して行われた決定の一部を出力しますRAMまたは直接GPU。これをいじってみると、次のようになりました。

Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in Host memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in VIDEO memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in Host memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in SYSTEM HEAP memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).

ここで行ったのは、PBOを使用して、テクスチャーの更新をGPUにストリーミングし、バッファーのマッピングを介してフレームごとに1つの更新を行いました。ここでの自然な選択はGL_STREAM_DRAWを使用することですが、GL_STATIC_DRAWを指定しました。ドライバーが行ったことは、最初にVRAMでバックアップされたバッファーをいくつか提供し、最初の2つの更新でI/Oマッピングを実行することでした。しかし、その後、考え方が変わり、クライアントが支援するバッファを使用します。そもそもGL_STREAM_DRAWを要求した場合に得られるであろう結果を正確に提供します。ここに表示されているのは、上記の引用されたテキストがsecond guessingの例です。

これらはすべて実装固有のものです。そして、それは前述のGL拡張が作成された理由の一部でもあります-これにより、プログラマーはそのようなことをより詳細に制御できるようになります。しかし、私の知る限り、この拡張は利用できません。 OpenGL ESの領域で。

7
derhass

IOSの場合、VBOに関する情報は here in Apple開発者サイトです。彼らのドキュメントによるとGL_DYNAMIC_DRAW and GL_STREAM_DRAW are equivalent.

しかし、私はあなたのソリューションはGL [DYNAMIC_DRAWに近いと思います。なぜなら、GL_DYNAMIC_DRAW is for vertex buffers that are rendered many times, and whose contents change during the rendering loop.

1
mert