2

好的,所以我正在研究我自己的 DirectX 框架所有关于制作 DirectX 框架的教程都是旧的并且使用了不推荐使用的东西所以我只是制作了我自己的,尽管我从旧教程中获取了一些东西并更新了它们以使用新的 Windows 8.1 SDK 和问题来了,我XMMATRIX在使用原始代码时遇到错误D3DXMATRIX

(33): error C2719: 'unnamed-parameter': formal parameter with __declspec(align('16')) won't be aligned
(40): error C2719: 'unnamed-parameter': formal parameter with __declspec(align('16')) won't be aligned
(42): error C2719: 'worldMatrix': formal parameter with __declspec(align('16')) won't be aligned
(42): error C2719: 'viewMatrix': formal parameter with __declspec(align('16')) won't be aligned
(42): error C2719: 'projectionMatrix': formal parameter with __declspec(align('16')) won't be aligned

这是 S_SHADER.h 的第 33 行:

bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX);

这是 S_SHADER.h 的第 40 行:

bool SetSHaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX);

这是 S_SHADER.cpp 的第 42 行:

41 - bool S_SHADER::Render(ID3D11DeviceContext* deviceContext, int indexCount, DirectX::XMMATRIX worldMatrix,  DirectX::XMMATRIX viewMatrix, DirectX::XMMATRIX projectionMatrix)
42 - {

实际上 41 包含所有代码,而 42 只有左括号,无论如何我做错了什么?

编辑: 不认为这会有所帮助,但我有一台带有 Visual Studio 2013 的 Windows 7 64 位计算机

4

1 回答 1

9

事实证明这相当复杂,并且在MSDN中有所介绍。

简短的回答是您需要使用调用约定友好的 typedef,这些 typedef 可以与 x86 __fastcall、x64 __fastcall、ARM __fastcall 和新的 VS 2013 x86/x64 __vectorcall 的各种组合一起使用。

“理想”的解决方案是:

bool XM_CALLCONV Render(ID3D11DeviceContext*, int, FXMMATRIX, CXMMATRIX, CXMMATRIX);

bool XM_CALLCONV SetSHaderParameters(ID3D11DeviceContext*, FXMMATRIX, CXMMATRIX, CXMMATRIX);

您的原始版本实际上会针对 x64 本机进行编译,但是每个 XMMATRIX 都被推入堆栈并且不会“在寄存器中”传递。x64 本机保证堆栈变量的 16 字节对齐。Win32 和 ARM 没有。

对于 x86 和 x64,VS 2013 支持新的调用约定“__vectorcall”,它可以在寄存器中传递前六 (6) 个 __m128 值,包括 XMMATRIX 等异构向量聚合 (HVA)。但是,任何不适合寄存器的东西都应该通过“常量引用”而不是“值”传递。

对于 VS 2012 及更低版本,x86 __fastcall 在寄存器中传递前三 (3) 个 __m128 值,但不能在寄存器中传递 HVA。由于堆栈变量的自然对齐,其余部分必须通过“常量引用”而不是“值”传递。

对于 VS 2012 及更低版本,x64 __fastcall 永远不会在寄存器中传递 __m128 值。虽然堆栈的自然对齐允许 XMVECTOR 和 XMMATRIX 作为堆栈上的副本通过“值”传递,但通过“常量引用”传递可能更有效。

对于 ARM,__fastcall 传递寄存器中的前四 (4) 个 __n128 值,并支持 HVA。在这种情况下,这将是一个 XMMATRIX。

因此 DirectXMath 的约定使用FXMVECTOR, GXMVECTOR, HXMVECTOR, CXMVECTOR,FXMMATRIXCXMMATRIX用于参数而不是直接使用XMVECTORor XMMATRIX。起初这可能有点复杂,但是由于编译器会报错,正如您在 Win32 中看到的那样,您可以通过一些试验和(编译器)错误来解决异常或复杂的情况。

或者,您不必担心向量和矩阵值的“最佳”寄存器传递行为,只需选择简单的方法,例如:

bool Render(ID3D11DeviceContext*, int, const XMMATRIX&, const XMMATRIX&, const XMMATRIX&);

bool SetSHaderParameters(ID3D11DeviceContext*, const XMMATRIX&, const XMMATRIX&, const XMMATRIX&);

这应该适用于所有架构和调用约定。

于 2014-08-14T06:43:04.817 回答