C++ 为什么在我的DX11游戏中加载了D3D10SDKLayers.dll?

C++ 为什么在我的DX11游戏中加载了D3D10SDKLayers.dll?,c++,windows,visual-studio-2010,directx-11,C++,Windows,Visual Studio 2010,Directx 11,请参见下面的编辑更新。原来的问题已被修改 我有一个使用DX11设备的工作窗口。当我尝试使用Alt+Enter全屏显示时,我的问题就出现了。如果窗口未聚焦,我会得到一个调试输出,其中显示: 'MyGame.exe':加载的'C:\Windows\SysWOW64\D3D10SDKLayers.DLL'无法找到或打开PDB文件 然后是警告 DXGI警告:IDXGISwapChain::Present:由于应用程序未正确使用IDXGISwapChain::ResizeBuffers、指定IDXGIOu

请参见下面的编辑更新。原来的问题已被修改

我有一个使用DX11设备的工作窗口。当我尝试使用Alt+Enter全屏显示时,我的问题就出现了。如果窗口未聚焦,我会得到一个调试输出,其中显示:

'MyGame.exe':加载的'C:\Windows\SysWOW64\D3D10SDKLayers.DLL'无法找到或打开PDB文件

然后是警告

DXGI警告:IDXGISwapChain::Present:由于应用程序未正确使用IDXGISwapChain::ResizeBuffers、指定IDXGIOutput::GetDisplayModeList中不可用的DXGI_模式描述或未使用DXGI_交换链标志_允许模式_开关,导致全屏演示效率低下

我相当肯定DX11游戏不应该加载D3D10SDKLayers.dll,尤其是在执行过程中。从MSDN文档中,我收集到这个dll是在设备创建时加载的:
如果设备是用适当的层标志创建的,这个dll会自动加载。因此,我检查了一下我的设备创建方法是否在执行过程中被调用,但实际上没有。在我的游戏中,只有两个位置存在设备创建,并且两个位置都没有被击中。
编辑:检查MSDN后,该dll似乎只是一个调试dll,可能只是加载以打印警告本身,而没有其他用途

显式复制案例:

1) Alt+Enter 6次(3个全屏转换周期,双向,启动窗口),第7次加载dll并弹出警告。无论窗口聚焦如何,这种情况都会发生。

方法调用层次结构摘要(全屏显示):

1) ToggleFullscreen()-我的方法,Alt+Enter调用的唯一方法
2) ResizeTargetAndBuffers()-我的方法,下面的子方法
3) DXGISwapChain->ResizeTarget(frontBufferDesc)将前缓冲区的大小调整为指定的大小
4) DXGISwapChain->GetFullscreenState()确定全屏状态
5) DXGISwapChain->SetFullscreenState(TRUE,NULL)以全屏显示
6) ResizeDXGIBuffers(宽度、高度、真值)我的方法,调整后缓冲区大小,下面的子方法
7) DXGISwapChain->调整缓冲区大小(计数、宽度、高度、格式、标志),以调整后缓冲区大小
8) DXGISwapChain->ResizeTarget(frontBufferDesc)可防止刷新率问题。RefreshRate成员根据MSDN最佳实践归零
9) DXGISwapChain->GetFullscreenState()确定全屏状态

方法调用层次结构摘要(打开窗口):

1) ToggleFullscreen()-我的方法,Alt+Enter调用的唯一方法
2) ResizeTargetAndBuffers()-我的方法,下面的子方法
3) DXGISwapChain->ResizeTarget(backBufferDesc)将前缓冲区的大小调整为指定的大小
4) DXGISwapChain->GetFullscreenState()确定全屏状态
5) DXGISwapChain->SetFullscreenState(FALSE,NULL)全屏显示
6) DXGISwapChain->ResizeTarget(backBufferDesc)将前缓冲区调整为窗口的分辨率(有助于解决一些分辨率问题)
7) ResizeDXGIBuffers(宽度、高度、假)我的方法,调整后缓冲区大小,下面的子方法
8) DXGISwapChain->调整缓冲区大小(计数、宽度、高度、格式、标志),以调整后缓冲区大小
9) DXGISwapChain->GetFullscreenState()确定全屏状态

其后果相当严重。我捕获Alt+Enter的低级键盘钩子不再被调用,因此windows能够自动执行Alt+Enter处理,它完全绕过我的ToggleFullscreen方法,并将窗口设置为桌面分辨率。这会导致缓冲区大小错误(因为我没有设置缓冲区,windows设置了缓冲区),导致低效警告,并干扰程序中的变量,这些变量不再正确了解缓冲区大小以及窗口是否全屏

你知道是什么导致了这一切吗

另外,如果您需要代码示例,请具体说明您希望看到的内容,如果可能的话,我会尝试将其张贴出来。我无法列出完整的代码清单

编辑:设备创建代码如下


         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%的时间都能成功,也就是说,当您不使用远程桌面时,所以我将只关注它。我给它一个适配器,driverType作为D3D\u DRIVER\u TYPE\u HARDWARE,m\u CreateFlags作为D3D11\u CREATE\u DEVICE\u DEBUG,m\u eFeatureLevel作为D3D\u FEATURE\u LEVEL\u 11\u 0。非常标准的呼叫,而且总是成功的

编辑更新1:经过大量调试后,我发现当加载dll并弹出低效警告时,会出现一些非常有趣的情况。它们列在下面:

1) VS2010调试器不再触发密钥挂钩中的断点
2) 打印输出不再在钥匙钩中工作。
3) 如果窗口在之前可重新调整大小,则它可能会变为不可重新调整大小
4) 窗口可能无法移动。
5) 三个线程退出

编辑更新2:第一次编辑更新可能有不正确的假设;如果我发现有,我会删除它。事实证明,我的低级键钩子不再被调用(我想,因为它里面没有断点或print语句),因此如果我的程序中有什么东西意外地注销了它,那么这将导致上述所有问题。明天测试这个

编辑更新3:我不确定到底发生了什么。我在家用电脑和工作电脑上测试了同一个clean项目,得到了不同的结果。在家里,我可以无限期地Alt+Enter而不会出现任何问题,但在工作中,Alt+Enter第7次会导致不再调用键挂钩,并且会发生缓冲区问题

编辑更新4:更多测试(工作中)。在第三次转换到窗口模式后,钥匙钩肯定会被移除。它不再在key-hook方法内部打印,断点也不会被触发,不管按了什么键。我想我要单独提一个问题,雷加

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 );
    }
}