無料ブログはココログ

« さくらや閉店 | トップページ | ( ̄ω ̄)ゞ г(*-ω`*)┘ »

2010年1月28日 (木)

ID3DX11Effect を Direct3D10( D3D_FEATURE_LEVEL_10_1 以下) で ?

August 2009 DirectX SDK から実装された Direct3D11 でエフェクトクラスは ID3DX11Effect に名前が変更されて、ソースコードが提供されているので自分でビルドする。

自宅の PC のビデオカードが Radeon5770 だったことこともあって問題なく動作していた。

試しに Direct3D10 用のビデオカードで動作確認したところ、

D3D11: ERROR: ID3D11Device::CreateVertexShader: The pClassLinkage parameter must be NULL, unless GetFeatureLevel returns D3D_FEATURE_LEVEL_11_0 or greater.

という感じで D3DX11CreateEffectFromMemory 関数は正常終了(SUCCEEDED)しているのにも関わらずデバッグ出力を見るとエラーが発生している。シェーダ自体は 4.0 で作っているので Direct3D10 でも動くはずだがシェーダ作成の時点で失敗している。try~catch でも捕まえられない。

せっかくソースコード付いているので追ってみると、EffectNonRuntime.cpp 内の

(m_pDevice->*(pShader->pVT->pCreateShader))( (UINT *) pShader->pReflectionData->pBytecode, pShader->pReflectionData->BytecodeLength, m_pClassLinkage, &pShader->pD3DObject) ) )

というところで失敗しているようだ。

デバッグ出力からこの処理で注目するところは m_pClassLinkage。Dynamic Shader Linkage は Direct3D11 の新機能で、Direct3D10 では利用できないはず。m_pClassLinkage は ID3D11Device::CreateClassLinkage で作成するが、ID3D11Device の D3D_FEATURE_LEVEL が 11 でなくても作成できてしまうのが問題なのではなだろうか。

これは将来的に直るのか、こういう仕様なのか、シェーダとか疎い自分には手に負えない。でもとりあえず Direct3D10 のボードが刺さった PC でも動かしたいので、EffectNonRuntime.cpp 内の

VH( m_pDevice->CreateClassLinkage( &m_pClassLinkage ) );

の部分を

if( m_pDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 )
{
    VH( m_pDevice->CreateClassLinkage( &m_pClassLinkage ) );
}

としてくくってやって、Direct3D10 以下では利用させないようにすることでとりあえずプログラムを動作させることができる。

来月には新しい DirectXSDK がリリースされるらしいので、この問題や個人的に気になっている点がいろいろ解決されているといいな・・・。

ちなみに上記で Direct3D10 という言葉を使っているが、意味合いとしては Direct3D11 で D3D_FEATURE_LEVEL_10_n という意味。Direct3D10 の API ではないので。

2010.02.12 追記

February 2010 DirectX SDK で直ったっぽい。

« さくらや閉店 | トップページ | ( ̄ω ̄)ゞ г(*-ω`*)┘ »

プログラミング」カテゴリの記事