2012-01-17 3 views
3

デバイスを初期化してすべてのイベントを処理するために、DXUTを使用するD3Dアプリケーションを作成しています。しかし、私は奇妙な動作を見つけました。アプリケーションを作成すると、アプリケーションの倍精度計算がすべて壊れてしまいます。いくつかのデバッグ後、私はこれにコードを簡素化:D3Dデバイスの作成後に二重計算を行うことができません

bool CALLBACK AlwaysTrue(D3DCAPS9*, D3DFORMAT, D3DFORMAT, bool, void*) { 
    return true; 
} 

INT WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, INT) { 
    // Commenting line below solves the problem. 
    DXUTSetCallbackD3D9DeviceAcceptable(AlwaysTrue); 
    DXUTInit(true, true); 
    DXUTCreateWindow(L"Issue with doubles"); 

    __int64 val = 1326778320508821LL; 
    double a1 = 0.000001 * val; // 1326778320.5088210 
    DXUTCreateDevice(true, 640, 480); 
    double a2 = 0.000001 * val; // 1326778368.0000000 

    DXUTMainLoop(); 
    return DXUTGetExitCode(); 
} 

まあ、私はかなり確信している、ここではフロート/ダブルの問題を持っているが、私はそれがトリガー取得方法を理解するために失敗し、どのようにそれを回避するには。私はasmレベルでデバッグしようとしましたが、そのコードはa1a2で100%同じで、FPUの状態の問題だと思っています。

メインメソッドの最初の行をコメントアウトすると問題が解決します。

ここで何が起こっているのか誰かが知っていますか、この問題について詳しく知るにはいくつかの文書がありますか?私のアプリケーションは間違いなく倍精度の計算が必要です。

PS。 VS2008 SP1、SSE/SSE2がオフ、浮動小数点モデル:正確。

答えて

4

デフォルトのフラグを使用してD3D9デバイスを作成すると、FPU精度が24ビットに設定されます。 これを防ぐために、デバイスの作成時にD3DCREATE_FPU_PRESERVEフラグを設定する必要があります。あなたは例外を有効にするには、FPUの状態を変更する場合には、ドキュメントがこれをやってからあなたを落胆DXSDK

注:デフォルトのFPUの状態で

Portions of Direct3D assume floating-point unit exceptions are masked; 
unmasking these exceptions may result in undefined behavior. 

あなたはしかし、問題ないはずです。私が思うに、この中にいること:

DXUTでこれを行うためには、あなたがDXUTSetCallbackDeviceChangingを介して設定されたModifyDeviceSettingsコールバックを使用する必要がありますが、すなわち:デバイス許容できるコールバックを設定すると、問題を修正理由として

bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, void* pUserContext) 
{ 
    assert(DXUT_D3D9_DEVICE == pDeviceSettings->ver); 

    pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_FPU_PRESERVE; 
} 

DXUTSetCallbackDeviceChanging(ModifyDeviceSettings); 

D3D9コールバックを設定してD3D9を使用するようにDXUTを強制します。 D3D9を使用するように強制しないと、D3D10デバイスを作成しようとします。 D3D10デバイスを作成してもFPUの状態は変わらないので、バグは消えてしまいます。

+0

ありがとうございます!これは役に立ちます。 Docsは、このアプローチがパフォーマンスを悪化させていると言いますが、今は計算の精度にもっと関心があります。 – real4x

+1

パフォーマンスのコメントはかなり前に書かれたことに注意してください(私は約8年かそこらと仮定しています)。現在のCPUでは、パフォーマンスの問題は、倍数の場合に処理するデータ量が多いためにキャッシュ圧が増えるだけです。コードを変更せずにFPUの精度を変更しても、アルゴリズムの動作に影響を与えない限り、パフォーマンスに影響はありません。 – zeuxcg

関連する問題