DirectX11, プログラム

D3DPreprocessでプリプロセス

1件のコメント

スクリプトやテキストデータを記述する際、Cプリプロセッサの機能があればかなり便利になります。しかし、それを実装するのは大変です。コンパイラ付属のプリプロセッサは入出力がファイルなので使い勝手がわるい。何かないか探していたところDirectxのシェーダコンパイラ関連の関数にD3DPreprocessというものを発見、使ってみる。

レースチップ XLRコネクト スロットルコントローラ RENAULT Megane III (2008 - 2016) エンジン1.6 16V Bifuel【RaceChip XLR Connect】品番1117正規品

D3DPreprocess(MSDN)
1
2
3
4
5
6
7
8
9
HRESULT D3DPreprocess(
  in   LPCVOID pSrcData,
  in   SIZE_T SrcDataSize,
  in   LPCSTR pSourceName,
  in   const D3D_SHADER_MACRO *pDefines,
  in   ID3DInclude pInclude,
  out  ID3DBlob *ppCodeText,
  out  ID3DBlob *ppErrorMsgs
);

HLSLコード用のプリプロセッサですが、スクリプトなどにも使えそうです。ファイルではなくデータ(メモリ)を指定します 【CX SUPERIOR】ダッシュマット for CXスーペリア ノアなどにお勧め! 70系 【送料無料】 充電制御車対応 バッテリー 日産 ローレル E-GNC35 用 AMS60B24R ACデルコ ACDelco メンテナンスフリー 充電制御対応 AMS NISSAN ニッサン 車 車用 60B24R カーバッテリー バッテリートラブル バッテリー上がり。引数には処理するデータのほかに、ID3DBlobで結果受け取り、/Dオプションに相当するD3D_SHADER_MACRO、そして#include処理を行うインターフェイスを指定します。

include処理のインターフェイス定義

#includeでのファイル読み込み処理を実装するインターフェイス(クラス)を指定します。プリプロセッサオプション/Iに相当する機能はD3DPreprocessにないためこのクラスで実装します。D3D_COMPILE_STANDARD_FILE_INCLUDEを指定するとデフォルトのinclude処理(カレントディレクトリとpSourceNameのディレクトリの検索)。

プリプロセス結果
コメント除去、include展開、define置き換えが行われます。それとプリプロセス前の行数とincludeしたファイル名がわかるように#lineが追加されます。スクリプトの解析などでエラー発生場所を特定できます(プリプロセス後の行数では発生場所がわからない)。
1
2
3
4
#line 6 "test.h"
 
lineからの行数でプリプロセス前のファイルと行数がわかる
ここはtest.hの8行目

サンプルコード

includeインターフェイス
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//D3DPreprocessでのinclude処理インターフェイス
// 検索パスを3つまで追加可能
class IInclude : public ID3DInclude
{
public:
    IInclude(const char* path0, const char* path1=nullptr, const char* path2=nullptr)
    {
        inc_path[0] = path0;
        inc_path[1] = path1;
        inc_path[2] = path2;
    }
    HRESULT __stdcall Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes)
    {
        switch(IncludeType) {
        // とりあえず""と<>の区別なし
        case D3D_INCLUDE_LOCAL://#include ""
        case D3D_INCLUDE_SYSTEM://#include <>
            break;
        default:
            return E_FAIL;
        }
 
        for(auto& p : inc_path){
            if(!p)continue;
            std::string path = p;
            path += pFileName;
 
            std::ifstream input;
            input.open(path.c_str(), std::ios::binary);
            if(!input.is_open())continue;
            size_t fsize = (size_t)input.seekg(0, std::ios::end).tellg();
            input.seekg(0, std::ios::beg);
 
            void* data = ::operator new(fsize);
            input.read(static_cast<char*>(data), fsize);
            *ppData = data;
            *pBytes = fsize;
            return S_OK;
        }
        return E_FAIL;
    }
 
    HRESULT __stdcall Close(LPCVOID pData)
    {
        ::operator delete(const_cast<void*>(pData));
        return S_OK;
    }
 
    const char* inc_path[3];//検索パス
};

使用例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    const char* file_path = "data/test.fx";
    const char* inc_path = "data/";
 
    std::ifstream input;
    input.open("data/test.fx", std::ios::binary);
    //if(input.is_open())//省略
    size_t fsize = (size_t)input.seekg(0, std::ios::end).tellg();
    input.seekg(0, std::ios::beg);
    void* data = ::operator new(fsize);
    input.read(static_cast<char*>(data), fsize);
 
    IInclude iinc(inc_path);// /I inc_path
 
    // Cプリプロセッサでの/Dオプション
    D3D_SHADER_MACRO defines[] = {
        {"DEBUG", "1"},// /DDEBUG=1
        {nullptr, nullptr},// I'll be back
    };
 
    ID3DBlob* result = nullptr;
    ID3DBlob* error = nullptr;
    D3DPreprocess(data, fsize, file_path, defines, &iinc, &result, &error);
 
    if(result)OutputDebugStringA( (const char*)result->GetBufferPointer() );
    if(error)OutputDebugStringA( (const char*)error->GetBufferPointer() );
 
    ::operator delete(data);
    if(result)result->Release();
    if(error)error->Release();
 
// コードの色付けのバグにより ¥¥⇒/

おまけ

OutputDebugStringA関数などでエラー出力を行う場合
ファイルパス(数字):エラー文
という書式で出力すると、ダブルクリックでファイルパスのファイルをVisualStudioのエディタで開き、数字で指定した行数にエディットカーソルが移動した状態になります 。

【UNTIL、バイオピュアマット、コイルマット、ラゲッジマット】ホンダ 新型フィットH/V GP5系 Bio Pure クッションコイル トランクマット HONDA FIT ロードノイズ低減コイルマット 【送料無料】

レースチップ XLRコネクト スロットルコントローラ RENAULT Megane III (2008 - 2016) エンジン1.6 16V Bifuel【RaceChip XLR Connect】品番1117

DOTTY JEEP チェロキー シートカバー EURO-LUX 2008.06~現在 ABA-KK37, PIRELLI(ピレリ) サマータイヤ 夏用タイヤ 275/35R22 SCORPION VERDE 275/35R22 104W XL VOL タイヤ単品 4523995105902, 【スピアーノ フロントシェイダー】HF21 ダークスモーク OXエヴォリューションワン (FS-179D, 15インチ サマータイヤ セット【適応車種:ヴォクシー(60系 全グレード)】WEDS ライツレー XS ブラックメタリックポリッシュ 6.0Jx15エナセーブ RV504 195/65R15, NISSAN Altima  スポイラー Painted For Nissan Altima 4D Sedan Rear Roof Spoiler 13-15 & Free LED Light 日産アルティマ4Dセダンリアルーフスポイラー13-15&フリーLEDライトのために描か 【代引不可】プロト:ネオプロト クランクプーリーNEO(ネオ) インプレッサ/レガシィ/フォレスター/エクシーガ/WRX STI [ジュラルミン ピンク(アルマイト)] スバル(EJ/EL系エンジン搭載車 NP, 【送料無料】 205/45R16 16インチ WORK ワーク エモーション 11R 6.5J 6.50-16 HANKOOK ハンコック ヴェンタス R-S4 Z232 サマータイヤ ホイール4本セット, 2輪 ビームス SS300ソニック B409-07-000 JAN:4582285330684 カワサキ エストレア Fi JBK-BJ250A 2007年~, 【エスペリア Espelir】ハイゼット/デッキバン 等にお勧め スーパーアップサス / フロント用左右セット 型式等:S321W 品番:ESD-2946F, K&H ケイアンドエイチ シート本体 ソロシート2 プレーン <セミオーダー> カラー:アルミニウム カラー:プレーンブラック FXSTD SOFTAIL DEUCE [ソフテイルデュース] ★送料無料★(一部離島等除く) 【キノクニ】ストレート(984012、アダプター ホース口(グチ) ストレート)

レースチップ XLRコネクト スロットルコントローラ RENAULT Megane III (2008 - 2016) エンジン1.6 16V Bifuel【RaceChip XLR Connect】品番1117:エンドレス CC-Rg リア左右セット ブレーキパッド クラウン UZS143/UZS145 EP281 取付セット ENDLESS ブレーキパット【店頭受取対応商品】 ワイドトレッドスペーサー【15mm】DEX/デックス/スバル/PCD 4H-100■キックス Kics W.T.S. ハブユニットシステム【2枚1SET】ワイトレ ツライチ 15ミリ/1.5cm/1.5センチ

レースチップ XLRコネクト スロットルコントローラ RENAULT Megane III (2008 - 2016) エンジン1.6 16V Bifuel【RaceChip XLR Connect】品番1117.Spoon リジカラ 1台分 [アウディ RS6 4F C6 4FBUHS 5.2 2006/7~] スプーン リジカラ 新品 [CUSCO] クスコ 車高調 ストリートゼロ ソアラ JZZ30 1991年05月~2000年12月 1JZ-GTE 2.5T FR ※北海道・沖縄・離島は送料別途

【送料無料】 195/50R15 15インチ OZ SPARCO トロフェオ 6J 6.00-15 DUNLOP ダンロップ ルマン 4(LM704) サマータイヤ ホイール4本セット ★送料無料★(一部離島等除く) 【200 ハイエース アールエスアール】車高調 ハイエースバン TRH200V FR 2000 NA [16/8~] TP Basic☆i KIT-2A(ショック+ブロックキット+バンプラバー)


ファイルパス(10,8)
とすると10行、8文字目にカーソルが移動 C11 ティーダ シートカバー【オートウェア】ティーダ C11 シートカバー モダン ブラック。
プリプロセスでエラーが発生したときに、ダブルクリックでエラー発生場所に移動できたので何か特殊なデバッグ機能がD3DPreprocessに備わっているのではと考えましたが、単にデバッグ出力を特定の書式にすることで有効になる機能でした。スクリプトやテキストデータの解析時に使えそうです プロジェクトμ ベストップ フロント左右セット ブレーキパッド プレミオ ZRT261 F136 プロジェクトミュー プロミュー プロμ BESTOP ブレーキパット【店頭受取対応商品】 【タナベ】【 サステック タワーバー 】 SUSTEC STURT TOWER BAR ストリーム RN7 R18A 2006年07月~2014年05月。