3

OpenGL/ES では、テクスチャへのレンダリング機能を実装するときに、フィードバック ループ (書き込み先と同じテクスチャからピクセルを読み取る) が発生しないように注意する必要があります。明らかな理由から、テクスチャの同じピクセルを読み書きするときの動作は未定義です。ただし、同じテクスチャの異なるピクセルを読み書きしている場合も未定義の動作ですか? 例としては、内部にレンダリング テクスチャを含むテクスチャ アトラスを作成しようとしていた場合です。テクスチャへのレンダリング中に、テクスチャ アトラスに保存されている別のテクスチャからピクセルを読み取ります。

テクスチャで同じピクセルを読み書きしていないので、データが同じテクスチャから来ているという理由だけで、動作は未定義と見なされますか?

4

4 に答える 4

3

ただし、同じテクスチャの異なるピクセルを読み書きしている場合も未定義の動作ですか?

はい。

ここでキャッシングが大きな問題になります。ピクセル データを書き込む場合、必ずしもすぐにイメージに書き込まれるとは限りません。書き込みはキャッシュに保存されるため、複数のピクセルを一度に書き込むことができます。

テクスチャ アクセスも同じことを行います。問題は、それらが同じキャッシュを持っていないことです。そのため、書き込みキャッシュにあるデータを書き込んだ可能性がありますが、テクスチャ キャッシュはそれを認識していません。

さて、仕様はここでは少し手荒です。理論的には、テクスチャのある領域から読み取り、別の領域に書き込むことができます (ただし、仕様では定義されていません)。 ただし、書き込んだ場所から読み取らない限り、またその逆も可能です。明らかに、それはあまり役に立ちません。

NV_texture_barrier 拡張機能を使用すると、これを回避できます。NVIDIA の拡張機能ですが、ATI ハードウェアでもサポートされています。その仕組みは、glTextureBarrierNVすべてのキャッシュをフラッシュしたいときに関数を呼び出すことです。そうすれば、ある場所から読み取るときに、その場所に書き込んだことを確認できます。

したがって、テクスチャの 1 つの領域を書き込み領域として指定し、別の領域を読み取り領域として指定するという考え方です。いくつかのものをレンダリングした後、リードバックを行う必要がある場合は、バリアを発射してテクスチャ領域を交換します。これはテクスチャのピンポンに似ていますが、新しいテクスチャをアタッチしたり、FBO をバインドしたり、ドローバッファを変更したりするという重い操作は必要ありません。

于 2011-06-24T02:07:34.107 に答える
1

問題は、フィードバックループの可能性ではなく(技術的にはループにはなりませんが、ピクセルの読み取り/書き込みの順序が定義されていないため、定義できない動作が発生します)、GPUが実装するアクセスモードの制限は次のとおりです。バッファ任意の時点でのみ読み取りまたは書き込みが可能です(ギャザーアクセスとスキャッターアクセス)。また、GPUは常にバッファー全体を認識します。これがその制限の主な理由です。

于 2011-06-23T19:50:16.593 に答える
0

はい、それでもそうです。GPUは超並列であるため、一度に1ピクセルずつ書き込むとは言えません。また、テクスチャの準備ができたときに読み込まれるキャッシュシステムもあります。同じテクスチャに書き込む場合は、キャッシュを同期する必要があります。

いくつかの洞察については、NV_texture_barrier OpenGL拡張機能を見てください。これは、この領域にある程度の柔軟性を追加することを目的としています。

于 2011-06-23T19:18:33.817 に答える
0

はい、テクスチャのさまざまな領域を読み書きすることも未定義です。しかし、それが未定義であるかどうかを気にするのはなぜですか。別のテクスチャに書き込んで、問題を完全に回避してください。

于 2011-06-23T19:19:39.813 に答える