DirectInput8的EnumDevices有时会非常缓慢

8
有时(大约50%的情况下),EnumDevices需要5-10秒才能返回。通常它几乎是瞬间完成的。我找不到任何其他关于这种行为的报告。
当速度变慢时,通过观察stdout来进行分析是可以的 :) 这个:
std::cout << "A";
directInput8Interface->EnumDevices(DI8DEVCLASS_GAMECTRL, MyCallback, NULL, DIEDFL_ATTACHEDONLY);
std::cout << "C";

...

BOOL CALLBACK MyCallback(LPCDIDEVICEINSTANCE, LPVOID)
{
    std::cout << "B";
    return DIENUM_CONTINUE;
}

似乎在枚举设备时会随机挂起 - 有时在回调被调用之前,有时在几次之后,有时在最后一次调用之后。
这显然是一个简化的代码块; 我实际上正在使用OIS输入库(http://sourceforge.net/projects/wgois/),因此,请查看完整的源代码以了解上下文。

http://wgois.svn.sourceforge.net/viewvc/wgois/ois/trunk/src/win32/Win32InputManager.cpp?revision=39&view=markup

虽然那里似乎没有什么特别有趣的事情,但可能是它们的初始化中的某些东西导致了这种情况 - 我不了解 DI8 足以发现它。

任何关于为什么会如此缓慢的想法都将不胜感激!

编辑:

我已经在 etl 跟踪文件中捕获了挂起,并在 Windows Performance Analyzer 中进行了分析。看起来 EnumDevices 最终调用 DInput8.dll!fGetProductStringFromDevice,后者调用 HIDUSB.SYS!HumCallUSB,后者调用 KeWaitForSingleObject 并等待。10 次中有 9 次(确切地说是 10 个样本中有 9 个),它会非常快速地返回(每个 324us),准备好的调用堆栈包含 usbport.sys!USBPORT_Core_iCompleteDoneTransfer,后跟 HIDUSB.SYS!HumCallUsbComplete,看起来相当正常。

但是在10次调用中,有1次几乎需要5秒才能返回。在准备调用堆栈中的ntkrnlmp.exe!KiTimerExpiration而不是HIDUSB.SYS函数。我猜这一切都表明HIDUSB.SYS驱动程序正在异步查询设备,超时时间为5秒,有时会失败并达到此超时。

我不知道这个故障是否与特定的任何一个设备相关(我有几个USB HIDs),或者它是否是随机的 - 这很难测试,因为它并不总是发生。再次强调,任何人可以给我的信息将不胜感激,尽管我不抱希望微软会在不同寻常的DirectInput处境下尽快修复这个问题!

也许我只能开始更早地异步初始化输入,并接受有时会出现5秒延迟的用户输入。

7个回答

9
我也遇到了这个问题,作为终端用户,多年来一直很困扰我。直到在一个开源项目上遇到了这个问题并进行了调试后,我才意识到这是一个问题。
结果发现是我的USB耳机DAC(来自Massdrop的Objective DAC)安装了驱动程序:wdma_usb.inf_amd64_134cb113911feba4\wdma_usb.inf,设备实例ID为USB\VID_262A&PID_1048&MI_01\7&F217D4F&0&0001,然后在设备管理器中以“声音、视频和游戏控制器”下的ODAC-revB USB DAC和“人体界面设备”下的USB输入设备HID兼容消费者控制设备显示。
我不知道HID条目的作用,但是当它们启用并将此DAC设置为音频输出设备时,IDirectInput8_CreateDevice和EnumDevices都非常缓慢。禁用“USB输入设备”条目似乎不会产生负面影响,并完全解决了我的问题。
将音频输出从DAC更改为其他任何内容也奇妙地解决了这个问题。
这太糟糕了,以至于使游戏手柄配置对话框joy.cpl无法使用,挂起并最终崩溃。
我本来想让这只是一个评论,但我没有足够的声望来发布评论,而这几乎是唯一描述此问题的互联网上的地方,所以希望这能有助于将来的某些人!

1
非常有趣!谢谢!我从来没有弄清楚这个问题,也从未在其他机器上遇到过这种情况,所以我认为可能是设备的问题,而你的报告也表明了同样的情况!很高兴知道我不是唯一受影响的人! - Ben Hymers
更新:有时它会安装不同的wdma_usb.inf驱动程序,该驱动程序也会出现相同的问题。不过,在我的新电脑上不再出现这个问题了。旧电脑是英特尔Haswell机器。 - RileyLabrecque
1
你真是个救星。我遇到这个问题已经有将近10年了。禁用了几个晦涩的“USB输入设备”条目,问题就解决了,从10秒降到了200毫秒。虽然所有这些设备都显示为“input.inf”,但没有一个与“wdma”有关。我以前也有一个Objective DAC(在它坏掉之前),但不是来自Massdrop。我想JDS Labs现在销售一些更新版本的产品,据说更不容易出问题:https://blog.jdslabs.com/2015/05/releasing-odac-revb/ 我会试着向他们请教,也许我们会学到一些有趣的东西。 - Zyl
一些额外的阅读材料,以便我们可以将所有这些信息链接到彼此:https://github.com/godotengine/godot/issues/20566https://github.com/pygame/pygame/issues/2173 - RileyLabrecque

3

我有同样的问题。我使用的是Corsair K65 LUX RGB键盘。我更新了CUE,这似乎解决了这个问题。


1

当我使用我的海盗船K55键盘时,遇到了同样的问题。更换USB端口的键盘可以暂时解决问题,但是后来问题又出现了。因此,这似乎是一个有缺陷的驱动程序问题。


有趣,我也遇到了同样的问题,目前使用的是Corsair K66键盘。 - Greg

1
DaFox所指出的,一个可能的原因是启用了某些设备驱动程序。我联系了JDS Labs支持(他们销售一种安装了此类驱动程序的设备),他们友善地指出,根本原因实际上是Windows中的一个错误(而不是安装的驱动程序),并且他们在其故障排除页面上提供了解决方案。请参见游戏挂起或经历加载延迟,其中明确提到了VID_262。禁用此驱动程序可以解决问题,没有明显的副作用(在这是唯一触发错误的驱动程序的情况下)。至于在Windows内部到底出了什么问题,这里就有龙了。
所以我想对于用户来说,最好的解决方案是收集所有您曾经连接到系统的所有设备的故障排除和常见问题页面,并查看是否提到了由驱动程序引起的延迟/卡顿。
作为一名软件开发人员,您可能希望对受影响的代码进行基准测试,并友好地告知用户系统配置存在问题以及在哪里查找如何修复它(如果执行时间不合理长)。

0

与海盗船K70键盘相同的问题。 快速重新连接键盘可以解决此问题,直到下一次发生。通常会在从系统中删除某些DirectInput设备或进入睡眠模式后发生。


0

似乎Steelseries Apex 7键盘也出现了同样的问题。拔下并重新插入该键盘可消除在枚举USB设备时出现的3次冻结(每次10秒)。


0

这个问题困扰着我作为开发者和我的朋友作为用户多年。所有使用DInput、SDL SDL_INIT_JOYSTICK或依赖它的游戏都需要非常长的时间来初始化。

这是由于DAC的驱动程序存在故障所致,正如DaFox指出的那样,禁用相应的USB输入设备可以解决这个问题。尽管它标有不同的制造商名称,但供应商ID匹配。

该设备的硬件ID为USB\VID_262A&PID_9023&REV_0001&MI_00


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接