我正在将C代码移植到HLSL(计算着色器)。 编译器对其中一个 for 循环很疯狂。在运行时,显示设备驱动程序检测到执行代码的时间不合理。
以下是带有问题 for 循环的部分源代码:
P = FloatToAsciiNoExponent(F * Factor, DstBuf, 7);
uint TmpBuf[FTOA_BUFFER_SIZE];
uint BytesWritten = IntToAscii(Exp10, TmpBuf, BASE10);
DstBuf[P++] = 'E';
[fastopt]
for (uint I = 0; I < BytesWritten; I++)
DstBuf[P++] = TmpBuf[I];
在运行时,我收到以下调试消息:
D3D11 错误: ID3D11设备::删除设备: 设备已删除 由于以下原因(DXGI_ERROR_DEVICE_HUNG:设备触发 执行其命令花费了不合理的时间,或者 硬件崩溃/挂起。因此,TDR(超时检测和 已触发恢复)机制。当前设备上下文为 发生挂起时执行命令。应用程序可能需要 重生并回退到不太积极地使用显示硬件)。 执行错误 #378:DEVICE_REMOVAL_PROCESS_AT_FAULT]
如果我注释掉两行 for 循环,一切都很好(当然除了缺少他最后一部分的最终结果)。
FloatToAsciiNoExponent()
是一个函数,它将他的第一个参数转换为存储在第二个参数(uint数组)中的列表或ASCII代码。最后一个参数是转换的数值基数。它已经过验证。
IntToAscii()
是一个函数,将他的第一个参数转换为存储在第二个参数(uint 数组)中的 ASCII 代码列表。它已经过验证。
我正在移植的原始 C 源代码可以在这里找到:https://searchcode.com/codesearch/view/14753060/
我运行在 2010 年 6 月的 Windows 7 和 DirectX SDK(最后一个在 Windows 7 上运行)。Windows 更新已执行,每个更新都已安装。显卡是NVidia Quadro K4200,具有24GB的RAM,驱动程序版本为431.02。
任何帮助表示赞赏。
使用 DirectCompute 时,您仍然需要确保每个实例在合理的时间内完成,否则您将遇到 TDR 超时(~2 秒)。
查看Microsoft文档
使用 DirectX 11.1(Windows 8 或更高版本),您可以使用D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT
为长时间运行的 DirectCompute 着色器留出更多时间,但可以使系统无响应。
您可以通过以下方式在 Windows 7 Service Pack 1 上安装 DirectX 11.1 的部分版本KB2670838
您还应该阅读此博客文章,了解有关旧版 DirectX SDK 的更多最新信息。
显然,这实际上是旧版DirectX SDK的HLSL编译器错误。请注意,即使对于Windows 7上的DirectX 11,您也可以并且应该使用最新的Windows 10 SDK HLSL编译器。请参阅此博客文章和Microsoft文档。
回答自己:
我将我的PC升级到包含DirectX12的Win10。现在源代码按预期工作。这确认 2010 年 6 月编译器存在错误。