You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows10 2018年4月更新后调用IDirect3D9::CreateDevice触发FPU异常

我之前在维护Delphi的Direct3D应用时,碰到过和你完全一样的问题——Win10 2018年4月更新后,双显卡笔记本切到NVIDIA独显就触发FPU除零崩溃,核显和旧系统都正常。临时用全局Set8087CW($133F)确实能解决,但总觉得不是长久之计,后来折腾出了根本的解决办法,分享给你:

问题的核心原因

这其实是NVIDIA显卡驱动在Win10 1803更新后的兼容性bug:当应用调用IDirect3D9::CreateDevice并传入D3DCREATE_FPU_PRESERVE标志时,NVIDIA驱动的初始化流程没有正确处理FPU控制字的状态,导致内部触发了未被捕获的浮点除零异常。这个bug只在双显卡场景下切换到NVIDIA独显时出现,Intel核显的驱动逻辑没有这个问题,旧版Windows的FPU状态管理机制也不会触发这个冲突。

根本解决步骤

1. 优先升级NVIDIA显卡驱动

NVIDIA在后续的驱动更新(大概是418.x版本及以后)中专门修复了这个FPU控制字的bug。建议你:

  • 卸载当前的NVIDIA驱动(可以用Display Driver Uninstaller彻底清理残留)
  • 到NVIDIA官网下载对应显卡型号的最新稳定版公版驱动(如果笔记本厂商允许安装公版驱动;若厂商限制,也可检查厂商官网的驱动更新,通常他们会同步NVIDIA的修复内容)
  • 安装后重启电脑,再测试应用,大概率能直接解决问题。

2. 若无法升级驱动,用局部FPU控制字切换替代全局设置

全局禁用FPU异常可能会影响应用中其他依赖FPU异常的代码(比如某些数值计算模块),所以可以只在CreateDevice的临界区临时修改FPU控制字:

var
  OldCW: Word;
begin
  // 保存当前FPU控制字
  OldCW := Get8087CW;
  try
    // 临时设置禁用所有FPU异常的控制字
    Set8087CW($133F);
    // 调用CreateDevice
    Result := D3D9.CreateDevice(Adapter, DeviceType, hWnd, BehaviorFlags, @PresentParams, Device);
  finally
    // 恢复原来的FPU控制字
    Set8087CW(OldCW);
  end;
end;

这种方式只会在创建D3D设备的短时间内修改FPU状态,不会影响其他代码逻辑。

3. 验证D3DCREATE_FPU_PRESERVE标志的正确性

虽然你说已经传入了这个标志,但要确认Delphi代码中该标志的定义是否正确。D3DCREATE_FPU_PRESERVE的正确值是$00000020,如果你的Direct3D单元里的定义错误,驱动不会识别这个标志,也就不会保留FPU状态,依然会触发异常。可以检查单元中的定义,或者直接用数值$20替代标志常量来测试。

额外说明

  • 为什么Intel核显没问题?因为Intel的驱动实现了正确的FPU状态保存与恢复逻辑,严格遵循了D3DCREATE_FPU_PRESERVE的要求。
  • 为什么旧Windows版本没这个问题?Win10 1803更新了内核层的FPU上下文切换机制,NVIDIA驱动当时没有及时适配这个变化,才导致了兼容性冲突。

内容的提问来源于stack exchange,提问作者Igor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:20:17