DirectX :: XMMATRIX错误C2719:__ declspec(对齐(' 16'))无法对齐

时间:2014-08-14 04:28:39

标签: c++ visual-studio-2013 directx directx-11 directxmath

好的,所以我正在开发自己的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位计算机

1 个答案:

答案 0 :(得分:9)

结果相当复杂,并在MSDN上进行了介绍。

简短的回答是你需要使用与x86 __fastcall,x64 __fastcall,ARM __fastcall和新VS 2013 x86 / x64 __vectorcall的各种组合一起使用的call-convention友好typedef。

'理想'解决方案是:

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

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

您的原始版本实际上是针对x64本机编译的,但是每个XMMATRIX都被压入堆栈并且未被传递" in-register"。 x64 native保证堆栈变量的16字节对齐。 Win32和ARM没有。

对于x86和x64,VS 2013支持新的调用约定" __ vectorcall"它可以传递寄存器中的前六(6)__m128值,包括异构向量聚合(HVAs),如XMMATRIX。但是,任何不适合注册的内容都应该通过&#const; const reference'传递。而非价值'。

对于VS 2012及更低版本,x86 __fastcall传递寄存器中的前三(3)个__m128值,但不能传递寄存器中的HVAs。其余部分必须通过&#const;参考'而非价值'由于堆栈变量的自然对齐。

对于VS 2012及更低版本,x64 __fastcall永远不会在寄存器中传递__m128值。虽然堆栈的自然对齐允许XMVECTOR和XMMATRIX通过'值'作为堆栈上的副本,通过&#const; const reference'代替。

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

因此,DirectXMath使用FXMVECTORGXMVECTORHXMVECTORCXMVECTORFXMMATRIXCXMMATRIX作为参数的约定而不是直接使用XMVECTORXMMATRIX。起初这可能有点复杂,但是由于编译器抱怨你已经看过Win32,你可以通过一点试验和(编译器)错误来解决异常或复杂的情况。

或者,您不必担心“最佳”。注册向量和矩阵值的传递行为,并选择简单的东西:

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

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

这应该适用于所有体系结构和调用约定。