2013-05-21 12 views
6

DirextX 7 SDKに対してプログラムされたソフトウェアがあります(コードではLPDIRECTDRAWSURFACE7などが使用されます)。フルスクリーンで動作します。主なタスクは、信頼できる方法で外部トリガーに応答して何かを画面上に置くことです。これは、Windows XPでは非常にうまく動作します。ソフトウェアはいくつかのトリガーを待ってトリガーされたときに新しいフレームを作成し、バックバッファーに入れて、DXにバッファーを反転するように指示します。その結果、トリガとフレームが画面上に効果的に表示される間のおおよその遅延は、ビデオカードとドライバに応じて、60Hzスクリーンでは3フレームまたは50mSecです。これは、すべてのNVidiaカードを実行しているさまざまなシステムでテストされています。より高いエンドカードを持ついくつかのシステムでは、2フレームも取得します。Windows 7でのDirectX 7レイテンシを修正しましたか?

しかし、Windows 7で他のソフトウェアをインストールしていない状態で同じソフトウェアを実行すると、5フレーム未満になることはありません。パイプラインのどこかで、OSやドライバ、あるいはその両方が2つの余分なフレームを食べることになりますが、これはアプリケーションにとって受け入れられないほどです。我々は、エアロ/デスクトップコンポジション/異なるドライババージョン/異なるビデオカードを無効にしようとしたが役に立たなかった。

  • これはどこから来たのですか?これはどこかに書かれていますか?
  • 簡単な方法で修正できますか?私はDirectX 7が古くなっていることを知っていますが、新しいバージョンをコンパイルするためにアップグレードすることは数多くの作業であり、別のタイプの修正がうまくいくでしょう。たぶんコードで設定できるフラグ?

編集はここでは関係と思われるいくつかのコードです:フロントの

作成/裏面:それらが描画される前に、フレームのレンダリングに使用される表面の

ddraw7->SetCooperativeLevel(GetSafeHwnd(), 
    DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED) 

DDSURFACEDESC2 desc; 
ZeroMemory(&desc, sizeof(desc)); 
desc.dwSize = sizeof(desc); 
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | 
         DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE | 
         DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; 
desc.dwBackBufferCount = 1; 
ddraw7->CreateSurface(&desc, &primsurf, 0) 

DDSCAPS2 surfcaps; 
ZeroMemory(&surfcaps,sizeof(surfcaps)); 
surfcaps.dwCaps = DDSCAPS_BACKBUFFER; 
primsurf->GetAttachedSurface(&surfcaps, &backsurf); 

作成:

DDSURFACEDESC2 desc; 
ZeroMemory(&desc, sizeof(desc)); 
desc.dwSize = sizeof(desc); 
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ; 
desc.dwWidth = w; 
desc.dwHeight = h; 
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; 
desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); 
desc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8; 

LPDIRECTDRAWSURFACE7 surf; 
HRESULT r=ddraw7->CreateSurface(&desc, &surf, 0) 

レンダリングループ、OnIdle

//clear surface 
DDBLTFX bltfx; 
ZeroMemory(&bltfx, sizeof(bltfx)); 
bltfx.dwSize = sizeof(bltfx); 
bltfx.dwFillColor = RGBtoPixel(r, g, b); 
backsurf->Blt(rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx) 

//blit some prerendered surface onto it, x/y/rect etc are calculated properly) 
backsurf->BltFast(x, y, sourceSurf, s&sourceRect, DDBLTFAST_WAIT); 

primsurf->Flip(0, DDFLIP_WAIT) 

primsurf->Blt(&drect,backsurf,&srect,DDBLT_WAIT,0); 
+0

これがなぜ控除されているのか説明してください。それがここに属していない場合は、少なくとも理由を教えてください。これはコーディングの質問のため、 – stijn

+0

は、stackoverflowでそれを尋ねる。 – magicandre1981

+0

ええ私は確信が持てませんでしたが、構成上の問題である可能性があります。とにかく近くに投票して投票しました – stijn

答えて

3

Windows XPは赤ちゃんだと思います。 DirectX 7を直接実行したWindowsの最後のバージョンはWindows 2000でした.Windows XPはWindows 7と同じようにDX9をDX7でエミュレートしています。

アプリケーションがパレット化されたテクスチャを使用し、DXがその機能をエミュレートすると(DX7の後にドロップされたとき)、インデックス付きの色を使用してテクスチャが生成されると思います。 GPUViewでアプリのプロファイリングを試して、テクスチャをGPUにプッシュする際に遅延がないかどうかを確認してください。たとえば、Win7ドライバが最初に圧縮しているのでしょうか?

+0

パレタイズされたテクスチャや他の特殊なDXのテクニックは使用していません。すべてがピクセル単位で表面メモリに書き込まれます。しかし、GPUViewに言及してくれてありがとう、それを知らなかったが、それは面白いようです。 – stijn

+0

@stijnあなたはどのシェーダを使っていますか? –

+0

いいえ。コードatmを持っていませんが、アフタークールでは、サーフェスのピクセルをレンダリングするだけで、サーフェスをバックバッファサーフェスに描画し、Flip()を呼び出します。 – stijn

関連する問題