当内存接近 2GB 时,我们遇到了旧的闭源游戏引擎无法编译着色器的问题。
问题通常与D3DXCreateEffect
. 通常它会返回 HResult“内存不足”,有时会d3dx9_25.dll
在弹出窗口中打印随机错误,或者它只是完全的段错误。
我相信问题在于缺乏大地址意识:我注意到其中一个d3dx9_25.dll
崩溃做了一些暗示这样的事情。它需要一个看起来像 的有效指针0x8xxxxxx3
,检查位0x80000003
是否点亮,如果是,则位反转指针并取消引用它。结果指针指向未分配的内存。在编译前强制引擎 malloc 2GB 会使着色器每次都无法编译。
不幸的是,我们对 DX9 的了解非常有限,我已经看到 DX9 有一个标志,D3DXCONSTTABLE_LARGEADDRESSAWARE
但我不确定它到底应该去哪里。我能找到的游戏使用的唯一 API 调用依赖于它D3DXGetShaderConstantTable
,但问题发生在它被调用之前。注射标志(1 << 17) = 0x20000
,以D3DXCreateEffect
使着色器以另一种方式失败编译。
是D3DXCreateEffect
应该接受较大的地址标志?我发现了一个使用它的wine 测试,但深入研究 DX9 程序集,它抛出的错误是由内部函数FFFFF800
在设置了in 标志中的任何位时返回 HResult Invalid Call 引起的,这让我相信CreateEffect
不应该接受这个标志.
在此之前还有其他地方我应该注入大地址感知标志吗?我知道D3DXGetShaderConstantTable
需要修复对使用的调用D3DXGetShaderConstantTableEx
,但它甚至还没有达到。