DirectX :: XMMATRIX __declspec(align('16'))将不会对齐

时间:2013-03-06 10:53:47

标签: c++ windows visual-studio-2012 directx directx-11

我正在使用DirectXMath构建我的3D模拟项目

   void SetConstantBuffer(ID3D11DeviceContext*_device_context, DirectX::XMMATRIX _world, DirectX::XMMATRIX _view, DirectX::XMMATRIX _projection)
   {
       ConstantBuffer const_buffer;
       const_buffer.View = DirectX::XMMatrixTranspose(_world);
       const_buffer.World = DirectX::XMMatrixTranspose(_view);
         const_buffer.Projection = DirectX::XMMatrixTranspose(_projection);
       _device_context->UpdateSubresource(m_const_buffer, 0, NULL, &const_buffer, 0, 0);
   }

我可能在DirectXMath中的SIMD标志上得到这些编译器错误:

  

错误C2719:'_ world':带__declspec的形式参数(对齐('16'))将不对齐
  错误C2719:'_ view':带__declspec的形式参数(对齐('16'))将不对齐
  错误C2719:'_ project':带__declspec的形式参数(align('16'))将不会对齐

没有将其转换为DirectX :: XMFLOAT4X4还有其他方法吗? 顺便说一下,我正在使用x86机器并在Visual Studio 2012 Express上进行编译。

3 个答案:

答案 0 :(得分:5)

通过const引用而不是值传递值。

void SetConstantBuffer(
    ID3D11DeviceContext*_device_context,
    const DirectX::XMMATRIX &_world,
    const DirectX::XMMATRIX &_view,
    const DirectX::XMMATRIX &_projection)

答案 1 :(得分:0)

__ declspec(align(16))不适用于根据Microsoft的堆栈变量:MSDN Align。我的测试表明这也适用于#pragma pack(16)

因此,堆栈变量需要存储为XMFLOAT4X4,并使用XMLoadFloat4x4和XMStoreFloat4x4(您试图避免的)转换为XMMATRIX和从XMMATRIX转换。

幸运的是,Direct3D中的大多数处理都是在视频卡中执行的。由于微软的设计决策不佳,偶尔会出现不必要的64字节副本,这一点应该是难以察觉的。

答案 2 :(得分:0)

MSDN: DirectXMath Library Internals

  

FXMMATRIX和CXMMATRIX别名有助于支持利用__vectorcall传递的HVA参数。

     

使用FXMMATRIX别名将第一个XMMATRIX作为参数传递给   功能。这假设您没有两个以上的FXMVECTOR   参数或两个以上的float,double或FXMVECTOR参数   矩阵的“右”。有关其他注意事项的信息,   请参阅__vectorcall文档。

     

否则使用CXMMATRIX别名。

DirectXMath Code

// Fix-up for (1st) XMMATRIX parameter to pass in-register for ARM64 and vector call; by reference otherwise
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || _XM_VECTORCALL_ ) && !defined(_XM_NO_INTRINSICS_)
typedef const XMMATRIX FXMMATRIX;
#else
typedef const XMMATRIX& FXMMATRIX;
#endif

// Fix-up for (2nd+) XMMATRIX parameters to pass by reference
typedef const XMMATRIX& CXMMATRIX;

<强>解决方案

如果您想支持更广泛的处理器体系结构,最好使用XM_CALLCONV宏来指定调用约定而不是硬编码__vectorcall

void XM_CALLCONV SetConstantBuffer(
    FXMMATRIX _world, 
    CXMMATRIX _view, 
    CXMMATRIX _projection, 
    ID3D11DeviceContext *_device_context) {
}