我正在使用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上进行编译。
答案 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别名。
// 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) {
}