我正在使用DirectXMath构build我的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(align('16'))的forms参数将不会alignment
错误C2719:'_view':具有__declspec(align('16'))的forms参数将不会alignment
错误C2719:'_projection':具有__declspec(align('16'))的forms参数将不会alignment
有没有其他方式没有将其转换为DirectX :: XMFLOAT4X4?
顺便说一句,我使用的是一台x86机器,并在Visual Studio 2012 Express上编译。
通过const引用而不是按值传递值。
void SetConstantBuffer( ID3D11DeviceContext*_device_context, const DirectX::XMMATRIX &_world, const DirectX::XMMATRIX &_view, const DirectX::XMMATRIX &_projection)
__declspec(align(16))不适用于根据Microsoft的堆栈变量: MSDN Align 。 我的测试表明这也适用于#pragma pack(16)
因此,需要将堆栈变量存储为XMFLOAT4X4,并使用XMLoadFloat4x4和XMStoreFloat4x4(您试图避免的)将其转换为XMMATRIX。
幸运的是,Direct3D中的大部分处理都是在显卡上执行的。 偶尔的,不必要的64字节拷贝是因为微软的糟糕的设计决定应该是不可察觉的。
void __vectorcall SetConstantBuffer( FXMMATRIX _world, FXMMATRIX _view, FXMMATRIX _projection, ID3D11DeviceContext*_device_context) { }
在使用__vectorcall
的情况下,您的3个参数将被放入XMM0,XMM1,XMM2寄存器,您将可以立即使用它们。 x86和x64版本都是这种情况。