私は(MacBook Proの網膜)比較的新しいマシン上でそれをしようとしたときglUseProgramが遅いのはなぜですか?
すべてがうまく働いていたOS X上でGLSLを使用して、異なるデバイスに異なるオーバーレイの数の映像をレンダリングすることができ、ビデオアプリケーションを書いてきましたしかし、私は今は古いマシン(MacPro 4,1、Nvidia GT 120)を持っており、ボトルネックに陥っています。私は解決策を見つけることを望んでいます。
私のアプリケーションは、基本的にテクスチャと単純なプリミティブをレンダリングします。私は別の仕事をするシェイダーをいくつか持っています。テクスチャを描画するために1つ、円を描画するために1つ、バーを描画するために1つ...基本的に、フレームバッファにレンダリングすることによってglUseProgram()
を使用してシェーダを順番に適用しています。
ほとんどの場合、レンダリングパスごとに実行は非常に高速ですが(< 5ミリ秒)、時には3〜4個のデバイスにサービスを提供しているときに20ミリ秒以上かかることがあります。フレームあたり24fps = 41.6667ms。
問題は、現在のコンテキストとしてコンテキストを設定した直後にglUseProgramを呼び出すことであることがわかりました。ここでは、コードがあります:
CGLSetCurrentContext(device.renderingContext);
CGLLockContext(device.renderingContext);
// Setting and locking the context sometimes causes an inevitable GL error.
// We must clear the error here to enable proper error checking below.
glGetError();
[device bindFramebuffer];
GetError();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glViewport(0.0f, 0.0f, deviceSize.width, deviceSize.height);
glUseProgram(self.texApplyShader.program);
GetError();
誰もこれが原因で、なぜそれが唯一の散発的に起こることができるかを教えてもらえますか?私の描画方法は理にかなっているのですか、それを一台のシェーダで行うのが良いでしょうか?
編集: 私はfreenodeのIRC上でいくつかのOpenGLの男と話をしてきたし、彼らはglUseProgramは自分自身を呼び出す可能性があることを教えてくれました。彼らは確かに正しいです。 OpenGLパイプラインは、シェーダを切り替える前に待機しているようです。 glFinish()
コールをglUseProgram()
の前に置き、今度はglFinish()
が常にかかります。私はパフォーマンスのリークを見つけるためにさらに見ていきます。
どのようにタイミングを特定しましたか?一般に、OpenGLはアプリケーションと非同期で動作するため、各コマンドの実行時間を実際に識別することはできません。 'glUseProgram'の前にいくつかの他のコマンドを実行する必要があるかもしれません。 'GetError'が' glGetError'を呼び出すと仮定すると、すべてのglGet *コマンドがパイプラインをフラッシュするので、これは間違いなくパフォーマンスの問題です。 – BDL
一方、現代のGPUでは、シェーダプログラムを変更することは、できるだけ高価な状態変更(ターゲットフレームバッファを最初に変更すること)が可能です。このNVIDIAプレゼンテーションの[スライド48](http://www.slideshare.net/CassEveritt/beyond-porting)を参照してください(絶対数は関係ありません、そのグラフの形があります)。 – peppe
@BDL:タイマークエリを使用すると、コマンドの所要時間を計測できますが、それ以外の場合は推測できます。たとえば、GLの実装では、バッファスワップが発生したときではなく、バックバッファを変更する最初のコマンドが発行されたときにVSYNCのブロッキングを遅延させる可能性があります。コマンドそのものが異常に遅く、避けたいものだと間違って信じているかもしれません...私はGLの暗黙的な同期*の動作が問題であると言います。ドライバは、それだけで知られている理由から、いくつかのコマンドをブロックします。 –