DirectXMathConvert.inl断言失败(DirectXMathConvert.(第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 "描述了一个在16字节边界上对齐的XMFLOAT4结构。"

这就是assert正在检查的内容。XMLoadFloat4A有一个XMFLOAT4是不够的,它只需要为list float成员(8字节)对齐,它需要一个XMFLOAT4A在16字节边界上对齐。这可能是出于性能原因,也可能是由于内在特性的要求。

通常XMFLOAT4A被标记为__declspec(align(16)),所以编译器知道他必须将这个结构体对齐到16字节。在你的情况下,你可以检查XMFLOAT4A的申报。我建议使用编译器开关/EP,它在预处理器阶段之后和编译器开始之前写出一个文件。这可以帮助您检测是否有一些宏与您的XMFLOAT4A声明混淆。

你还应该检查到底是哪个调用失败了。

还有:MSDN有一篇关于__declspec(align(#))的文章。这就是说,如果你将一个XMFLOAT4A的值传递给一个函数,那么你就失去了对齐。在您的代码中,我只看到通过引用传递,但这仍然是一个值得记住的有趣的点。

相关内容

  • 没有找到相关文章

最新更新