2012-01-19 9 views
4

以下のアップデートをご覧ください。オリジナルの質問が修正されました!DX11ゲームでD3D10SDKLayers.dllが読み込まれるのはなぜですか?

DX11デバイスを使用している作業ウィンドウがあります。 Alt + Enterを使って全画面表示しようとすると、私の問題が発生します。ウィンドウがフォーカスされていない場合は、私が言うのデバッグ出力を取得:

'MyGame.exe': Loaded 'C:\Windows\SysWOW64\D3D10SDKLayers.DLL', Cannot find or open the PDB file

をして、警告を

DXGI Warning: IDXGISwapChain::Present: Fullscreen presentation inefficiencies incurred due to application not using IDXGISwapChain::ResizeBuffers appropriately, specifying a DXGI_MODE_DESC not available in IDXGIOutput::GetDisplayModeList, or not using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH

私はDX11ゲームはD3D10SDKLayersをロードしてはいけませんかなり確信しています.dll、特に実行中です。 MSDNのドキュメントから、私はこのdllがデバイスの作成時にロードされることを確認しました:if a device is created with the appropriate layer flag, this DLL is loaded automatically。だから私は自分のデバイスの作成方法が途中で何とか呼び出されていたかどうかを調べましたが、そうではありません。私はゲームの中にデバイス創造が存在する2つのスポットしかなく、どちらのスポットもヒットしていません。 EDIT:MSDNをチェックした後、このdllはデバッグdllだけであり、他の目的ではなく、警告自体を出力するために読み込まれる可能性があります。

明示的な再生の場合:

1)Alt +ウィンドウを開始、6回(3フルスクリーン遷移サイクル、両方の方法を入力してください)は、7日にDLLがロードされ、警告がポップアップ。これはウィンドウのフォーカスに関係なく発生します。

メソッド呼び出し階層の概要(予定フルスクリーン):

1)ToggleFullscreen() - 私の方法、+
2)ResizeTargetAndBuffers()を入力しますAltキーによって呼び出される唯一の方法 -
以下の私の方法、サブ方法を
6フルスクリーンへ行く 3)DXGISwapChain-> ResizeTarget(frontBufferDesc)は
5フルスクリーンの状態を決定するために、指定された解像度
4)DXGISwapChain-> GetFullscreenState()とフロントバッファのサイズを変更)DXGISwapChain-> SetFullscreenState(TRUE、NULL)) ResizeDXGI私のメソッド、バックバッファー、サブメソッドのサイズを変更する
7)DXGISwapChain-> ResizeBuffers(count、width、height、format、flags)バックバッファのサイズを変更する
8)DXGISwapChain-> ResizeTarget (frontBufferDesc)はリフレッシュレートの問題を防ぎます。 RefreshRateメンバは、MSDNのベストプラクティスに従ってゼロになっています。
9)DXGISwapChain-> GetFullscreenState()フルスクリーン状態にウィンドウ行く

メソッド呼び出し階層の概要()を決定します

1)ToggleFullscreen() - 私の方法、Altキーによって呼び出された唯一の方法は+
を入力します。 2)ResizeTargetAndBuffers() - サブメソッド
3以下私の方法)DXGISwapChain-> ResizeTarget(backBufferDesc)がフルスクリーン状態
5を決定するために、指定された解像度
4)DXGISwapChain-> GetFullscreenState()とフロントバッファのサイズを変更)DXGISwapCh AIN->
7)いくつかの解像度の問題を解決する助けた(ウィンドウの解像度にフロントバッファのサイズを変更するには、フルスクリーン
6)DXGISwapChain-> ResizeTarget(backBufferDescを)どこへ行くSetFullscreenState(FALSE、NULL))ResizeDXGIBuffers(幅、高さ、FALSE)私のこの方法は、

フルスクリーンの状態を決定するために)DXGISwapChain-> GetFullscreenState()バッファ
9をバックサイズを変更するバッファ、
8以下のサブメソッド)DXGISwapChain-> ResizeBuffersを(フラグ、フォーマット、高さ、幅をカウント)バックリサイズ

これの影響は非常に深刻です。 Alt + Enterをキャッチしている私の低レベルキーボードフックはもはや呼び出されないので、ウィンドウは自動的にToggleFullscreenメソッドをバイパスし、ウィンドウをデスクトップ解像度に設定する、自動的なAlt + Enter処理を行うことができます。これは、バッファを間違ったサイズにしてしまいます(ウィンドウを設定しなかったため)、非効率な警告が発生し、バッファサイズの正確な知識がなく、ウィンドウがフルスクリーンであるかどうかを知ることができませんか否か。

これを引き起こしている可能性のある候補はありますか?

P.S.コードサンプルが必要な場合は、見たいものについて具体的にしてください。可能であれば、それを記述しようとします。コードリスト全体を載せることはできません。

EDIT:デバイス作成コードは以下のとおりです。


     hr = D3D11CreateDevice( pAdapter, 
            driverType, 
            NULL, 
            rDeviceSettings.m_CreateFlags, 
            &rDeviceSettings.m_eD3DDeviceFeatureLevel, 
            1, 
            D3D11_SDK_VERSION, 
            &pGraphicsDevice, 
            &eFeatureLevel, 
            &pDeviceContextI 
      ); 


      if (FAILED(hr)) { 
       pAdapter = NULL; 
       // Remote desktop does not allow you to enumerate the adapter. In this case, we let D3D11 do the enumeration. 
       if (driverType == D3D_DRIVER_TYPE_UNKNOWN) { 
        hr = D3D11CreateDevice(pAdapter, 
              driverType, 
              NULL, 
              rDeviceSettings.m_CreateFlags, 
              &rDeviceSettings.m_eD3DDeviceFeatureLevel, 
              1, 
              D3D11_SDK_VERSION, 
              &pGraphicsDevice, 
              &eFeatureLevel, 
              &pDeviceContextI 
        ); 
       } 

最初の呼び出しは、つまりリモートデスクトップを使用していないときの99%の時間に成功します。したがって、私はそれだけに焦点を当てます。 D3D_DRIVER_TYPE_HARDWAREとしてのdriverType、D3D11_CREATE_DEVICE_DEBUGとしてのm_CreateFlags、およびD3D_FEATURE_LEVEL_11_0としてのm_eFeatureLevelをアダプタに与えます。かなり標準的な呼び出し、それは常に成功します。

EDIT UPDATE 1:広範なデバッグの後で、DLLがロードされ、非効率的な警告がポップアップすると、非常に興味深い状況が発生することがわかりました。それらは以下にリストされています:

1)VS2010デバッガはもはやキーフックのブレークポイントをトリガしません。
2)印刷出力はキーフックでは機能しません。
3)ウィンドウがサイズ変更可能であれば、サイズ変更不可能になる可能性があります。
4)ウィンドウが移動不能になることがあります。
5)スレッドのトリオが終了します。

編集更新2:最初の編集更新に間違った前提がある可能性があります。私がそれを見つけるなら、私はそれを削除します。私の低レベルのキーフックはもはや呼び出されていないことが判明しました。ブレークポイントやプリントステートメントは内部では機能しないので、私のプログラム内の何かが誤って登録解除されていると、 。この明日のテスト...

編集の更新3:もう何が起こっているのか分かりません。私は自宅のコンピュータと仕事用のコンピュータで同じクリーンなプロジェクトをテストし、異なる結果を得ました。家では、問題なくAlt + Enterを無期限に実行できますが、Alt + Enterキーを押すと、キーフックが呼び出されなくなり、バッファの問題が発生します。

編集の更新4:より多くのテスト(作業中)。 3回目のウィンドウモードへの移行後、キーフックが確実に削除されます。これはキーフックメソッドの中ではもはや印刷されず、押されたキーに関係なくブレークポイントはトリガされません。上で説明した他のすべての問題はToggleFullscreen()を呼び出さないキーフックの結果にすぎないので、これについて別の質問を開くつもりだと思います。参考までに、私は以下のキーフックコードを提供しました。


LRESULT _stdcall MyClass::WindowsKeyHook(s32 nCode, WPARAM wParam, LPARAM lParam) { 
    printf("Key hook called, nCode: %d. ", nCode); 
    if(nCode < 0 || nCode != HC_ACTION) { // do not process message 
     return CallNextHookEx(MyClassVar.GetWindowsKeyHook(), nCode, wParam, lParam); 
    } 
    printf(" Key hook status ok.\n"); 

    BOOL bEatKeystroke = FALSE; 
    KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam; 
    switch(wParam) { 
     //NOTE: Alt seems to be a system key when it is PRESSED, but a regular key when it is released... 
     case WM_SYSKEYDOWN: 
      if(p->vkCode == VK_MENU || p->vkCode == VK_LMENU || p->vkCode == VK_RMENU) { 
       MyClassVar.SetAltPressed(TRUE); 
      } 
      if(MyClassVar.IsAltPressed() && p->vkCode == VK_RETURN) { 
       bEatKeystroke = TRUE; 
       MyClassVar.SetAltEnterUsed(TRUE); 
       printf("Alt+Enter used.\n"); 
      } 
      break; 
     case WM_SYSKEYUP: 
      //NOTE: releasing alt+enter causes a SYSKEYUP message with code 0x13: PAUSE key... 
      break; 
     case WM_KEYDOWN: 
      break; 
     case WM_KEYUP: { 
      if(p->vkCode == VK_MENU || p->vkCode == VK_LMENU || p->vkCode == VK_RMENU) { 
       MyClassVar.SetAltPressed(FALSE); 
      } 
      bEatKeystroke = (!MyClassVar.IsShortcutKeysAllowed() && 
           (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN)); 
      break; 
     } 
    } 

    if(bEatKeystroke) { 
     return 1; 
    } 
    else { 
     return CallNextHookEx(MyClassVar.GetWindowsKeyHook(), nCode, wParam, lParam); 
    } 
} 

printfステートメントは、6番目のAlt + Enterの直後までキーフックが呼び出されていることを示しています。これはウィンドウモードへの第3の移行です。私が前に考えたように、問題を引き起こすために全画面表示を4回目にする必要はありません。 MyClassVarによって呼び出されるすべてのメソッドは、ウィンドウのキーフックにタイムアウトがあることを知っているので、キーフックをできるだけ速くするためにインラインです。 Alt + Enterの実際の処理は、MyClassのスレッドによって処理されます。

また、誰かがこれをコミュニティのWikiではないのですか?私は、この質問は、Wikiとして使用するにはあまりにも具体的すぎると思います。それが1つになった唯一の理由は、編集して定期的に更新していることです。

+0

実行中にデバイスの作成が行われないことに言及していますが、最初のデバイス作成からのフラグではありませんでしたか?また、あなたのデバイスの作成を表示することも可能です。 – josephthomas

+0

@josephthomas私は要求されたコードを追加しました。全画面表示に切り替えるときにのみ警告が表示されるため、初期のデバイス作成時のフラグであるとは限りません。これは私のフルスクリーントグルコードのエラーを示していますが、私はそれが何であるか分かりません。 – Darkhydro

答えて

1

この問題は、キーフックを完全に取り除くことで解決しました。 Alt + Enterを処理する適切な方法は、スワップチェーンを作成してからIDXGIFactory1::MakeWindowAssosciation(m_hWnd, DXGI_MWA_NO_ALT_ENTER)と呼ぶことです。次に、WM_SYSKEYDOWNWM_KEYUPを使用して、ウィンドウのメッセージ手順から独自のコードでAlt + Enterを処理できます。これが他人を助けることを願っています私はこれがうまくいくまで時間をかけていたので、自分のアプリで動かすのに苦労しているなら、私にメッセージを送ってください。私はあなたを助けようとします!

関連する問題