オフライン コンパイル
エフェクト コンパイラ ツール (fxc.exe) は、HLSL シェーダーおよびエフェクトのオフライン コンパイル用に設計されたツールです。このツールは次の場所にあります。
(SDK root)¥Utilities¥Bin¥x86¥
- 現在のコンパイラによるコンパイル
- レガシー コンパイラによるコンパイル
- 現在のコンパイラによるシェーダー モデル 1 のコンパイル
- サブプロセスでのエフェクト コンパイラ ツールの使用
Direct3D 9 と Direct3D 10 の違い December 2006 SDK から、(コード生成においてさまざまな点が向上した) DirectX 10 HLSL コンパイラ (エフェクト コンパイラ ツール) がデフォルト コンパイラとなっています。引き続き DirectX 9 コンパイラの規則 (fxc.exe) と照合してコンパイルするアプリケーションについては、/LD スイッチを指定して fxc.exe を使用することができます (これには D3DX9_31.DLL が必要です)。 DirectX 10 HLSL コンパイラでは、ps_1_x シェーダーを直接サポートしていません。ps_1_x シェーダーで fxc を使用する場合は、下位互換を有効にするために /Gec スイッチが必要です。ps_1_x ターゲットを指定するエフェクトは、代わりに ps_2_0 ターゲットをコンパイルします。これは DirectX 10 コンパイラによってサポートされている最小のシェーダー バージョンであるためです。このスイッチには、上位レベルのコンパイル ターゲットで使用される場合、エフェクトはありません。 |
現在のコンパイラによるコンパイル
現在のコンパイラでサポートされているシェーダー モデルについては、「プロファイル」を参照してください。次の例では、シェーダー モデル 4 をターゲットとして BasicHLSL10.fx ファイル内のエフェクト (「BasicHLSL10 サンプル」を参照) をコンパイルします。
// For a release build fxc /T fx_4_0 /Fo BasicHLSL10.fxo BasicHLSL10.fx
この例の説明は、次のとおりです。
- fx_4_0 は、ターゲット プロファイルです。
- BasicHLSL10.fxo は、コンパイルされたエフェクトを含む出力オブジェクト ファイルです。
- BasicHLSL10.fx は入力エフェクト ファイルです。
// For a debug build fxc /Od /Zi /T fx_4_0 /Fo BasicHLSL10.fxo BasicHLSL10.fx
デバッグ オプションには、コンパイラの最適化を無効にしたり、行番号やシンボルなどのデバッグ情報を有効にしたりする追加オプションがあります。シェーダーのバイナリ表現は、fxc 出力ファイルの任意の省略形である BasicHLSL10.fxo という名前のファイルに書き込まれます。
コマンド ライン オプションのリストについては、「構文」のページを参照してください。
ターゲットに fx_2_0 または fx_4_0 を指定して fxc.exe ツールを使用することで、エフェクトをオブジェクト ファイルにコンパイルできます。このオブジェクト ファイルを使用することで、D3DXCreateEffect (Direct3D 9) または D3D10CreateEffectFromMemory (Direct3D 10) を使用してエフェクトを直接作成できます。
レガシー コンパイラによるコンパイル
Direct3D 10 から、一部のシェーダー モデルがサポートされなくなっています。これには、ピクセル シェーダー モデルのps_1_1、ps_1_2、ps_1_3、および ps_1_4 があります。これらのモデルは、サポートするリソースが非常に限られているほか、ハードウェアに依存します。コンパイラは、シェーダー モデル 2 (またはそれ以降) に対応するように設計し直されており、コンパイルの効率をさらに向上させることができます。このためには、シェーダー モデル 2 以降をサポートするハードウェアで実行している必要があります。
引き続きレガシー コンパイラを使用してシェーダーをコンパイルする場合は、/LD スイッチを使用します。この場合、シェーダー モデル 1、2、および 3 がサポートされ、現在のコンパイラに組み込まれている機能の向上やバグ修正は含まれません。
また、/Gec スイッチの影響を受ける動作については、使用しているバージョンの エフェクト コンパイラ ツール に関連する SDK リリース ノートを参照してください。
現在のコンパイラによるシェーダー モデル 1 のコンパイル
シェーダー モデル 1 のピクセル シェーダーによって生じる制限のため、新しいシェーダー コードをコンパイルする際に、レガシー コンパイラを使用することはお勧めしません (「レガシー コンパイラによるコンパイル」を参照してください)。ただし、ps_1_x 用に作成された既存のシェーダーのライブラリはあります。
現在のコンパイラを使用してシェーダー モデル 1 のピクセル シェーダーおよびエフェクトを作成するには、/Gec スイッチを使用します。これにより、エフェクト コンパイラ ツールがすべての ps_1_x ターゲットを ps_2_0 ターゲットにコンパイルします。このために、既存のシェーダーまたはエフェクトのコードを変更する必要はありません。このスイッチには、上位レベルのコンパイル ターゲットで使用される場合、エフェクトはありません。
サブプロセスでのエフェクト コンパイラ ツールの使用
fxc.exe をサブプロセスとしてアプリケーションで生成した場合、そのアプリケーションでは、CreateProcess 関数に渡される出力パイプまたはエラー パイプ内のデータの有無をチェックしてそのデータを読み取る必要があります。アプリケーションがこのサブプロセスの完了を待機しているのみで、他の処理を実行していない場合、いずれかのパイプがいっぱいになると、このサブプロセスはいつまでも完了しません。
次のコード例では、サブプロセスを待機し、サブプロセスに割り当てられた出力パイプとエラー パイプを読み取る処理を示しています。WaitHandles 配列の内容は、サブプロセスのハンドル、stdout のパイプ、および stderr のパイプに対応しています。
HANDLE WaitHandles[] = { piProcInfo.hProcess, hReadOutPipe, hReadErrorPipe }; const DWORD BUFSIZE = 4096; BYTE buff[BUFSIZE]; while (1) { DWORD dwBytesRead, dwBytesAvailable; dwWaitResult = WaitForMultipleObjects(3, WaitHandles, FALSE, 60000L); // Read from the pipes... while( PeekNamedPipe(hReadOutPipe, NULL, 0, NULL, &dwBytesAvailable, NULL) && dwBytesAvailable ) { ReadFile(hReadOutPipe, buff, BUFSIZE-1, &dwBytesRead, 0); streamOut << std::string((char*)buff, (size_t)dwBytesRead); } while( PeekNamedPipe(hReadErrorPipe, NULL, 0, NULL, &dwBytesAvailable, NULL) && dwBytesAvailable ) { ReadFile(hReadErrorPipe, buff, BUFSIZE-1, &dwBytesRead, 0); streamError << std::string((char*)buff, (size_t)dwBytesRead); } // Process is done, or we timed out: if(dwWaitResult == WAIT_OBJECT_0 || dwWaitResult == WAIT_TIMEOUT) break; }
プロセス生成の詳細については、CreateProcess のリファレンス ページを参照してください。