DirectXMathConvert.inl 断言失败(DirectXMathConvert.inl 行 704)
DirectXMathConvert.inl assertion failure (DirectXMathConvert.inl line 704)
有人愿意将这段代码翻译成人类可读的吗?
|704| assert(((uintptr_t)pSource & 0xF) == 0);
基本上这个断言在我的程序中失败了,但不是 100% 的时间(没有我重新编译任何东西)这很奇怪。
完整的 XMLoadFloat4A
函数是(第 697 行 - DirectXMathConvert.inl):
|697| _Use_decl_annotations_
|698| inline XMVECTOR XM_CALLCONV XMLoadFloat4A
|699| (
|700| const XMFLOAT4A* pSource
|701| )
|702| {
|703| assert(pSource);
|704| assert(((uintptr_t)pSource & 0xF) == 0);
|705| #if defined(_XM_NO_INTRINSICS_)
|706| XMVECTOR V;
|707| V.vector4_f32[0] = pSource->x;
|708| V.vector4_f32[1] = pSource->y;
|709| V.vector4_f32[2] = pSource->z;
|710| V.vector4_f32[3] = pSource->w;
|711| return V;
|712| #elif defined(_XM_ARM_NEON_INTRINSICS_)
|713| return vld1q_f32_ex( reinterpret_cast<const float*>(pSource), 128 );
|714| #elif defined(_XM_SSE_INTRINSICS_)
|715| return _mm_load_ps( &pSource->x );
|716| #endif
|717| }
用例:
// Convert an XMFLOAT4A to XMVECTOR
XMVECTOR getXMVECTORfromXMFLOAT4A(const XMFLOAT4A& v) {
return XMLoadFloat4A(&v);
}
XMVECTOR foo = getXMVECTORfromXMFLOAT4A(XMFLOAT4A(1.0, 2.0, 3.0, 1.0));
// Transform XMFLOAT4A with XMMATRIX
XMFLOAT4A XMFloat4Transform(const XMFLOAT4A& v, const XMMATRIX& m) {
XMVECTOR vec = XMLoadFloat4A(&v);
XMVECTOR rot = XMVector4Transform(vec, m);
XMFLOAT4A result;
XMStoreFloat4A(&result, rot);
return result;
}
XMMATRIX m = XMMatrixLookAtLH(...);
XMFLOAT4A foo (1.0, 2.0, 3.0, 1.0);
XMFLOAT4A bar = XMFloat4Transform(foo, m);
为什么这个断言会失败?为什么不是 100% 的时间?
正如MSDN所说XMFLOAT4A
"Describes an XMFLOAT4 structure aligned on a 16-byte boundary."
这就是 assert
正在检查的内容。 XMLoadFloat4A
有一个 XMFLOAT4
是不够的,它只需要为 ist float 成员(8 字节)对齐,它需要一个在 16 字节边界上对齐的 XMFLOAT4A
。这可能是出于性能原因或因为内在函数需要它。
通常XMFLOAT4A
被标记为__declspec(align(16))
,所以编译器知道他必须将这个结构对齐到16字节。在您的情况下,您可以检查 XMFLOAT4A
的声明。我建议使用 compiler switch /EP
,它会在预处理器阶段之后和编译器启动之前写出一个文件。这可能会帮助您检测某些宏是否与您的 XMFLOAT4A
声明混淆。
您还应该检查具体是哪个调用失败了。
另外:MSDN 有一个 article on __declspec(align(#))。这表示,如果您按值将 XMFLOAT4A
传递给函数,那么您将失去对齐。在您的代码中,我只看到通过引用传递,但这仍然是一个需要牢记的有趣点。
有人愿意将这段代码翻译成人类可读的吗?
|704| assert(((uintptr_t)pSource & 0xF) == 0);
基本上这个断言在我的程序中失败了,但不是 100% 的时间(没有我重新编译任何东西)这很奇怪。
完整的 XMLoadFloat4A
函数是(第 697 行 - DirectXMathConvert.inl):
|697| _Use_decl_annotations_
|698| inline XMVECTOR XM_CALLCONV XMLoadFloat4A
|699| (
|700| const XMFLOAT4A* pSource
|701| )
|702| {
|703| assert(pSource);
|704| assert(((uintptr_t)pSource & 0xF) == 0);
|705| #if defined(_XM_NO_INTRINSICS_)
|706| XMVECTOR V;
|707| V.vector4_f32[0] = pSource->x;
|708| V.vector4_f32[1] = pSource->y;
|709| V.vector4_f32[2] = pSource->z;
|710| V.vector4_f32[3] = pSource->w;
|711| return V;
|712| #elif defined(_XM_ARM_NEON_INTRINSICS_)
|713| return vld1q_f32_ex( reinterpret_cast<const float*>(pSource), 128 );
|714| #elif defined(_XM_SSE_INTRINSICS_)
|715| return _mm_load_ps( &pSource->x );
|716| #endif
|717| }
用例:
// Convert an XMFLOAT4A to XMVECTOR
XMVECTOR getXMVECTORfromXMFLOAT4A(const XMFLOAT4A& v) {
return XMLoadFloat4A(&v);
}
XMVECTOR foo = getXMVECTORfromXMFLOAT4A(XMFLOAT4A(1.0, 2.0, 3.0, 1.0));
// Transform XMFLOAT4A with XMMATRIX
XMFLOAT4A XMFloat4Transform(const XMFLOAT4A& v, const XMMATRIX& m) {
XMVECTOR vec = XMLoadFloat4A(&v);
XMVECTOR rot = XMVector4Transform(vec, m);
XMFLOAT4A result;
XMStoreFloat4A(&result, rot);
return result;
}
XMMATRIX m = XMMatrixLookAtLH(...);
XMFLOAT4A foo (1.0, 2.0, 3.0, 1.0);
XMFLOAT4A bar = XMFloat4Transform(foo, m);
为什么这个断言会失败?为什么不是 100% 的时间?
正如MSDN所说XMFLOAT4A
"Describes an XMFLOAT4 structure aligned on a 16-byte boundary."
这就是 assert
正在检查的内容。 XMLoadFloat4A
有一个 XMFLOAT4
是不够的,它只需要为 ist float 成员(8 字节)对齐,它需要一个在 16 字节边界上对齐的 XMFLOAT4A
。这可能是出于性能原因或因为内在函数需要它。
通常XMFLOAT4A
被标记为__declspec(align(16))
,所以编译器知道他必须将这个结构对齐到16字节。在您的情况下,您可以检查 XMFLOAT4A
的声明。我建议使用 compiler switch /EP
,它会在预处理器阶段之后和编译器启动之前写出一个文件。这可能会帮助您检测某些宏是否与您的 XMFLOAT4A
声明混淆。
您还应该检查具体是哪个调用失败了。
另外:MSDN 有一个 article on __declspec(align(#))。这表示,如果您按值将 XMFLOAT4A
传递给函数,那么您将失去对齐。在您的代码中,我只看到通过引用传递,但这仍然是一个需要牢记的有趣点。