C++ 为什么在我的DX11游戏中加载了D3D10SDKLayers.dll?
请参见下面的编辑更新。原来的问题已被修改 我有一个使用DX11设备的工作窗口。当我尝试使用Alt+Enter全屏显示时,我的问题就出现了。如果窗口未聚焦,我会得到一个调试输出,其中显示: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
'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 );
}
}