ID3D11ShaderReflectionでシェーダコード解析

CreateInputLayoutで入力レイアウト(ID3D11InputLayout)を作成する際、頂点シェーダが要求する入力パラメータが不足しているとエラーコード(E_INVALIDARG)を返します。ただ作成が失敗するだけならいいのですが、エラーログが出力されてしまうため、シェーダを解析して入力パラメータの不足を調べるようにします。

ID3D11ShaderReflection

このインターフェイスでシェーダの入出力パラメータ、定数バッファの変数名などの情報が取得できます。作成にはD3DReflect関数を使用します。頂点シェーダ以外のシェーダも可能です。

リンクエラー

コンパイル&リンクするとIID_ID3D11ShaderReflectionが見つからないというリンクエラーが発生するため、dxguid.libをリンカー入力に追加します。

入力レイアウトのチェック

// 入力レイアウトチェック
// 頂点シェーダが要求している入力パラメータが定義されているか
// shader_code,code_size シェーダをコンパイルしたバイトコード
bool CheckInputLayout(const void* shader_code, size_t code_size,
					  const D3D11_INPUT_ELEMENT_DESC* layout, size_t layout_num)
{
	ID3D11ShaderReflection* vs_ref; 
	HRESULT hr = D3DReflect( shader_code,code_size,
				IID_ID3D11ShaderReflection, (void**)&vs_ref);
	// dxguid.libのリンクが必要
	if( FAILED( hr ) )return false;

	// シェーダ情報取得
	D3D11_SHADER_DESC shd_desc;
	hr = vs_ref->GetDesc(&shd_desc);
	if( FAILED( hr ) ){
		vs_ref->Release();
		return false;
	}

	for(UINT ip=0;ip<shd_desc.InputParameters;++ip){
		D3D11_SIGNATURE_PARAMETER_DESC desc;
		hr = vs_ref->GetInputParameterDesc(ip, &desc);
		if( FAILED( hr ) ){
			vs_ref->Release();
			return false;
		}
		
		//入力レイアウトに必要なセマンティク名がなければ利用不可
		UINT il=0;
		for(il=0;il<layout_num;++il){
			if( strcmp(layout[il].SemanticName, desc.SemanticName) == 0){
				break;
			}
		}
		if( il==layout_num){
			vs_ref->Release();
			return false;//見つからない
		}
	}

	return true;
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

認証:数字を入力してください(必須) * Time limit is exhausted. Please reload CAPTCHA.