OpenGL ES 2.0 と GLSL をいじる度に、シェーダー プログラムがハードウェア上でどのように実行されるのか正確に疑問を呈しています。頂点シェーダー プログラムとフラグメント シェーダー プログラムの背後にある概念はよく理解していますが、それらが金属でどのように機能するかについてはまだ非常に不明です。GPU について読んでいると、パイプラインという用語に出くわすことがよくあります。GPU には特定の数のパイプラインがあります。
パイプラインの機能を理解しています。パイプラインは一連の頂点 (ジオメトリック プリミティブを表す) を受け取り、指定されたパラメーターを使用して頂点シェーダーを実行し、それらの出力に基づいて操作を実行する固定機能ハードウェアを介して頂点シェーダーの出力を送信します。また、頂点シェーダーは、プリミティブの各フラグメントで補間された値を出力し、フラグメント シェーダーに入力するため、一般的なアルゴリズムを使用して多くの複雑なレンダリングを簡単に実行できます。
しかしこれは、GPU に n 個のパイプラインがある場合、任意の時点で n 個のパイプラインのそれぞれが単一のジオメトリ プリミティブのシェーダー プログラムのインスタンスを実行できることを意味するのでしょうか?
私は OpenGL ES 2.0 プログラミング ガイドを読んでいます (Kindle によると約 60% を読んでいます) が、おそらく私のまだ発展途上の理解のせいで、まさにこの質問に対する答えを見逃しているのでしょう。
私がこの質問をする実際的な理由の 1 つは、GPU ではなく CPU で実行すべき作業と実行すべきでない作業に関するものです。たとえば、単一の更新およびレンダリング スレッドを操作している場合、すべてのオブジェクトの行で実行する必要がある場合、CPU で行列をベクトル乗算するのは賢明ですか? それとも、複数のジオメトリ プリミティブの描画を実行するシェーダー プログラムを異なるパイプラインで同時に実行できる GPU にアウトソーシングする方がよいでしょうか?
それぞれの個別の描画呼び出しではなく、VBO を使用して画面上に多くのクワッドを描画するようにコードを最適化することに取り組んでいます。しかし、これは配列レンダリングと見なされるため、mvp マトリックスがクワッドの 4 つの頂点ごとに同じであっても、頂点ごとにすべてのマトリックスを GPU に送信する必要があります。これは帯域幅のヒットと見なすことができます。しかし、シェーダー プログラムが、CPU 上のレンダリング スレッドで次々に実行されるのではなく、同時に実行される場合、おそらくそれは価値のあるトレードオフです。しかし、私はどちらかと言えばそのレベルの専門知識を持っていません。