2012-01-10 1 views
8

私は、ゲームの世界を移動する際に、レベルデータ(シェーダーを含む)をストリームする大規模なゲームを開発しています。シェーダーがコンパイル/リンクされたり、初めて使用されたりすると、フレームレートにヒッチがないようにしたいと思います。独自のコンテキストで背景スレッドのシェーダを予熱できますか?

シェイダーのコンパイルとリンクは、独自のopen-glコンテキストを持つ別のスレッドで動作します。しかし、シェーダの予熱を別のスレッドで処理することはできませんでした(シェーダが最初に使用されたときにパフォーマンスが低下することはありません)。

予熱は実際にはiOSまたはOpenGLドキュメントのどこにも記載されていません。ただし、OpenGL ESアナライザ(xcodeからプロファイリングする際に使用できる計測器の1つ)に記載されています。このツールでは、以前に何かをレンダリングするのに使用されていないシェーダで何かがレンダリングされるたびに、 "予熱段階の外にシェーダをコンパイルしました"という警告が表示されます。

"OpenGL ESアナライザは、初期予熱段階の一部ではないシェーダのコンパイルを検出しました。シェーダのコンパイルには時間がかかることがあります。これらを避けるには、レンダリングに使用するすべてのシェーダを予熱します。これを行うには、あなたのアプリケーションが起動され、使用される各シェーダープログラムで描画呼び出しを実行し、シェーダープログラムが使用される任意のgl状態設定を使用してブレンド、カラーマスク、ロジックオプション、マルチスキャン、テクスチャ形式、およびポイントプリミティブ状態は、すべてシェーダのコンパイルに影響します。

「コンパイル」という用語はここで少し混乱します。頂点シェーダとフラグメントシェーダはすでにコンパイルされており、プログラムはリンクされています。しかし、何かが与えられたOpenGL状態で最初にレンダリングされるとき、それはシェイダー上で、私が推測するその状態のためにそれを最適化するために、より多くの作業を行います。

私は最初に使用する前にゼロサイズの三角形をレンダリングすることによってシェーダを予熱するコードを用意しています。

メインフレーム上のシェーダをコンパイルしてリンクして、通常のレンダリングと同じOpenGLコンテキストでプリウォーミングしている場合は動作します。しかし、別のOpen GLコンテキストを使用してバックグラウンドスレッド上で実行すると、動作しません(最初の使用時にAnalyzerの警告が表示されます)。

だから、別のコンテキストでシェーダを予熱することは、他のコンテキストに影響を与えないことがあります。あるいは、私は別の文脈をすべて同じ状態に設定する必要はありません。設定が必要なOpenGLの潜在的な可能性があります。バックグラウンドスレッドでオフスクリーンのレンダリングバッファを使用しているため、状態の一部と考えることができます。

予備的なウォームをバックグラウンドスレッドで処理することに成功した人はいますか?

答えて

6

私はしばらくの間、私のエンジンの最適化に取り組んできましたが、正直言って昨日まで私はこのことについて全く知らなかったのです。だから、まず、ヒントをお願いします:)。

シェイダーウォーミングのトピック以来、私は研究してきました。

私が言及に「ATI OpenGLのプログラミングと最適化ガイド」と題する文書で公式AMD文書を発見した:

http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=6&ved=0CEoQFjAF&url=http%3A%2F%2Fdeveloper.amd.com%2Fmedia%2Fgpu_assets%2FATI_OpenGL_Programming_and_Optimization_Guide.pdf&ei=3HIeT_-jKYbf8AOx3o3BDg&usg=AFQjCNFProzLiXf5Aqqs4jZ2jOb4x0pssg&sig2=6YV7SVA97EFglXv_SX5weg

これは、シェーダの温暖化を意味しているの抜粋です。

引用:

R500は、ネイティブフラグメントシェーディング部、R300及びR400 ASICSにフロー制御をサポートしていますがありません。 R300とR400の静的フロー制御は、ドライバによって、設定された定数に基づいて、使用されていない条件付きループとアンロールループをコンパイルしてエミュレートされます( )。 R500 asicsファミリ がフロー制御をネイティブにサポートしていても、ドライバは静的なフロー条件をコンパイルしようとしますが、より良い命令スケジューリングのためにシェーダ命令を再編成できます。また、ドライバは、再利用を予期して設定された特定の静的フロー条件のために、コンパイル済みシェーダを にキャッシュしようとします。だから、 スタティックフローコントロールを使用するフラグメントプログラムを書くときは、シェーダの寿命に関連する共通の静的条件 順列を使用する最初のフレームにダミーの三角形をレンダリングすることによって、シェーダキャッシュ を「ウォームアップ」することをお勧めします。

私の周りに見つけた最良の説明は以下の通りです:

http://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part-1/

引用:

。なお、これはまた、あなたが遅れあなたが初めて使用するときに頻繁に表示されます理由です新しいシェーダまたはリソース。多くの作成/編集作業はドライバによって延期され、実際に必要なときにのみ実行されます(いくつかのアプリが作成した未使用のものがどれくらいのものかは信じられません)。グラフィックスプログラマーはストーリーのもう片面を知っています。何かが実際に作成されたことを確認したい場合(メモリを予約しているのとは対照的に)、それを使って "ウォームアップ"するダミーのドローコールを発行する必要があります。醜いと厄介なことですが、1999年に初めて3Dハードウェアを使用し始めて以来、これが当てはまりました。つまり、この点では人生の事実です。 :)

このプレゼンテーションでは、ほとんどのDirectXに関連していますが、クライテックが遠くのエンジンでそれをどのように実行したかが記載されています。

http://www.powershow.com/view/11f2b1-MzUxN/Far_Cry_and_DirectX_flash_ppt_presentation

私はこれらのリンクが何らかの方法で助けを願っています。

+0

リンクありがとうございます。私はこの問題がPC上にも存在していることを知りました。私は、OpenGL ESでのこのような人々の経験にもっと興味があります。誰かがiOSや別のOpenGL ESプラットフォームでこの作業をして、知っていれば大丈夫です。それ以外の場合は、レベルで使用できるすべてのシェーダと使用されているコンテキストを事前に計算し、最初のロード中にそれらをあらかじめ暖めておくシステムの開発に頼る必要があります。 – Namaste

+0

期限切れのAtiのリンク。新しいもの:http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/ATI_OpenGL_Programming_and_Optimization_Guide.pdf –

関連する問題