OpenGLは最低レベルでどのように機能しますか?[閉まっている]


84

私はOpenGL / DirectXプログラムの書き方を理解しており、その背後にある数学と概念的なものを知っていますが、GPU-CPU通信が低レベルでどのように機能するのか興味があります。

三角形を表示し、カメラを45度回転させるCで記述されたOpenGLプログラムがあるとします。このプログラムをコンパイルすると、一連のioctl呼び出しに変換され、gpuドライバーが適切なコマンドをgpuに送信します。ここで、三角形を回転させ、適切な色で適切なピクセルを設定するすべてのロジックが配線されます。に?それとも、プログラムは「gpuプログラム」にコンパイルされ、gpuにロードされ、回転などが計算されますか?それともまったく違うものですか?

編集:数日後、私はこの記事シリーズを見つけました。これは基本的に質問に答えます:http//fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part- 1 /


OpenGL仕様では、コマンドはクライアント/サーバーモードで送信されると規定されています。仕様が広すぎて、OpenGL実装で使用される特定の技術を決定できません。
ルカ

回答:


86

OpenGL自体は単なるフロントエンドAPIであるため、この質問に答えることはほとんど不可能です。実装が仕様に準拠し、結果がこれに準拠している限り、任意の方法で実行できます。

問題は、OpenGLドライバーが最低レベルでどのように機能するかということだったかもしれません。ドライバーはハードウェアの一部に密接に関連しているため、これも一般的に答えることは不可能です。ハードウェアは、開発者が設計したものの、再び何かを行う可能性があります。

したがって、質問は「OpenGLとグラフィックシステムの舞台裏で平均してどのように見えるか」ということでした。これを下から上に見てみましょう:

  1. 最下位レベルには、いくつかのグラフィックデバイスがあります。現在、これらは、動作を制御するレジスタのセット(正確にはデバイスに依存するレジスタ)を提供するGPUであり、シェーダー用のプログラムメモリ、入力データ(頂点、テクスチャなど)用のバルクメモリ、および残りのI / Oチャネルを備えています。データとコマンドストリームを受信/送信するシステムの

  2. グラフィックドライバは、GPUの状態とGPUを利用するすべてのリソースアプリケーションプログラムを追跡します。また、アプリケーションによって送信されたデータの変換またはその他の処理を担当します(テクスチャをGPUでサポートされているピクセル形式に変換し、GPUのマシンコードでシェーダーをコンパイルします)。さらに、アプリケーションプログラムへの抽象的なドライバ依存インターフェイスを提供します。

  3. 次に、ドライバーに依存するOpenGLクライアントライブラリ/ドライバーがあります。Windowsでは、これはopengl32.dllを介してプロキシによってロードされますが、Unixシステムでは、これは2つの場所にあります。

    • X11GLXモジュールとドライバー依存のGLXドライバー
    • および/usr/lib/libGL.soには、直接レンダリング用のドライバー依存のものが含まれている場合があります

    MacOS Xでは、これはたまたま「OpenGLフレームワーク」です。

    OpenGL呼び出しを、(2)で説明されているドライバーの部分のドライバー固有の関数への呼び出しに変換するのはこの部分です。

  4. 最後に、実際のOpenGL APIライブラリ、WindowsおよびUnixのopengl32.dll / usr / lib / libGL.so。これはほとんどの場合、コマンドをOpenGL実装に適切に渡すだけです。

実際のコミュニケーションがどのように行われるかを一般化することはできません。

Unixでは、3 <-> 4接続は、ソケット(はい、必要に応じてネットワーク経由)または共有メモリ経由で発生する可能性があります。Windowsでは、インターフェイスライブラリとドライバクライアントの両方がプロセスのアドレス空間に読み込まれるため、通信はそれほど多くありませんが、単純な関数呼び出しと変数/ポインタの受け渡しが行われます。MacOS XではこれはWindowsに似ていますが、OpenGLインターフェイスとドライバクライアントの間に分離がない点が異なります(MacOS Xが新しいOpenGLバージョンに追いつくのが非常に遅い理由であり、新しいバージョンを提供するには常に完全なオペレーティングシステムのアップグレードが必要ですフレームワーク)。

3 <-> 2間の通信は、ioctl、読み取り/書き込み、または一部のメモリをプロセスアドレス空間にマッピングし、そのメモリに変更が加えられるたびに一部のドライバコードをトリガーするようにMMUを構成することによって行われます。これは、常にカーネルとユーザーランドの境界を越える必要があるため、どのオペレーティングシステムでも非常によく似ています。最終的には、システムコールを実行します。

システムとGPU間の通信は、ペリフィアルバスとそれが定義するアクセス方法を介して行われるため、PCI、AGP、PCI-Eなどは、ポートI / O、メモリマップドI / O、DMA、IRQを介して機能します。


1
この説明はおそらく低レベルで一般的すぎて、OpenGLの詳細はほとんどありません。これは、コンピューターに存在するすべてのハードウェアコンポーネントに大まかに適用されます。
v.shashenko 2016

1
@ v.shashenko:もちろんです。話しているハードウェアコンポーネントに関係なく、この一般的なスキームに従います。ただし、OpenGLは特定のソフトウェアではなく、単なる仕様であり、仕様に準拠するものはすべて有効な実装です。そして、最終的にOpenGL実装はGPUと通信するため、APIに面するハードウェアが実装されるのとほぼ同じスクリプトに従います。「そこではないので、それよりも、より具体的になることは不可能だONE」OpenGLの実装。そして、すべての実装は少し異なります。
datenwolf 2016

1
@ v.shashenko:詳細が必要な場合は、特定の実装について質問する必要があります。たとえば、X11 + GLX + DRI→Mesa / AMDGPU→Linux-KMS + DRM(ダイレクトレンダリングマネージャー)などです。そして、これらの各コンポーネントは非常に多くの詳細を備えたかなり複雑な獣であるため、各コンポーネントがどのように機能するかについての詳細を本に記入することができます。しかし、それはLinux-AMDGPUの実装を説明するでしょう。しかし、Linux + NVidiaはまったく別の獣です。そして、Windowsでは再び異なります。
datenwolf 2016

数日前にチャットしたことを覚えていますか?何か知りたい場合に連絡する方法を知りたかっただけです。
Suraj Jain 2016

あなたがその日に教えたことは、私の疑問の多くを取り除き、いくつかの新しい疑問も作りましたが、全体として、私たちが画面にウィンドウやアイコンを描くことは魔法ではないと思います。
Suraj Jain 2016

23

このプログラムをコンパイルすると、一連のioctl呼び出しに変換され、gpuドライバーが適切なコマンドをgpuに送信します。ここで、三角形を回転させ、適切な色で適切なピクセルを設定するすべてのロジックが配線されます。に?それとも、プログラムは「gpuプログラム」にコンパイルされ、gpuにロードされ、回転などが計算されますか?

あなたはそう遠くないです。プログラムは、インストール可能なクライアントドライバーを呼び出します(これは実際にはドライバーではなく、ユーザースペース共有ライブラリです)。これは、ioctlまたは同様のメカニズムを使用して、カーネルドライバーにデータを渡します。

次の部分では、ハードウェアによって異なります。古いビデオカードには、いわゆる「固定機能パイプライン」がありました。ビデオカードには、マトリックス専用のメモリスペースと、テクスチャルックアップ、ブレンディングなどの専用ハードウェアがありました。ビデオドライバは、これらの各ユニットに適切なデータとフラグをロードし、DMAを設定して頂点データ(位置)を転送します。 、色、テクスチャ座標など)。

新しいハードウェアには、ビデオカード内にプロセッサコア(「シェーダー」)があり、それぞれの動作がはるかに遅いという点でCPUとは異なりますが、並行して動作するものは他にもたくさんあります。これらのビデオカードの場合、ドライバーはGPUシェーダーで実行するプログラムバイナリを準備します。


20

プログラムは特定のGPU用にコンパイルされていません。OpenGLを実装するライブラリに対して動的にリンクされているだけです。実際の実装には、OpenGLコマンドのGPUへの送信、ソフトウェアフォールバックの実行、シェーダーのコンパイルとGPUへの送信、またはOpenGLコマンドへのシェーダーフォールバックの使用が含まれる場合があります。グラフィックスケープはかなり複雑です。ありがたいことに、リンクすることで、ドライバーの複雑さのほとんどからあなたを隔離し、ドライバーの実装者が適切と思われるテクニックを自由に使用できるようにします。


18

C / C ++コンパイラ/リンカは、テキストファイルをCPU上で実行される一連のマシン固有のオペコードに変換するという1つのことを実行します。OpenGLとDirect3Dは単なるC / C ++ APIです。C / C ++コンパイラ/リンカーをGPU用のコンパイラ/リンカーに魔法のように変換することはできません。

作成したC / C ++コードのすべての行は、CPUで実行されます。OpenGL / Direct3Dの呼び出しは、場合によっては静的または動的のC / C ++ライブラリを呼び出します。

「gpuプログラム」が機能する唯一の場所は、コードが明示的にシェーダーを作成する場合です。つまり、OpenGL / D3Dに対してAPI呼び出しを行うと、シェーダーのコンパイルとリンクが発生します。これを行うには、(C / C ++コンパイル時ではなく、実行時に)シェーダー言語でシェーダーを表す文字列を生成またはロードします。次に、それらをシェーダーコンパイラーに通し、そのシェーダーを表すAPI内のオブジェクトを取得します。次に、1つまたは複数のシェーダーを特定のレンダリングコマンドに適用します。これらの各ステップは、前述のようにCPU上で実行されるC / C ++コードの指示で明示的に実行されます。

多くのシェーダー言語は、C / C ++のような構文を使用します。しかし、それではC / C ++と同等にはなりません。


私は最近openglを学んでいて、なぜこれらすべての「シェーダープログラム」を文字列として書かれたコードで見るのか疑問に思っています。あなたが言ったように、それらは実行時にコンパイルされます。私はいくつかのアンドロイドopenglesコードでいくつかの例を見ました。それから私はiphone用のコードもいくつか見ました。どうやらiPhoneには4つのベクトルプロセッサがあり、iPhoneのCPUよりもはるかに高速に浮動小数点演算を実行できます。したがって、ASMをリテラル文字列として記述して、実行時にコンパイルし、メインCPUの代わりにそれらのプロセッサを使用できます。
eggie5 2011年

1
「固定関数パイプライン」のほとんどは、デフォルトのシェーダープログラムのセットによって実装されるようになりました。シェーダーを取得するために、明示的にシェーダーを要求する必要はありません。
Ben Voigt 2011年

1
@Ben Voigt:本当ですが、誰もあなたに言わなければ、違いを言うことはできません。
ニコルボーラス2011年

1
この質問が隠された詳細に関するものでなければ、これは賢明な態度かもしれません。
Ben Voigt 2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.