1
\$\begingroup\$

I want to ask a question about D3DXMATRIX and D3DXMATRIXA16, and how to use them with Havok Physics.

I'm using Visual Studio 2012 on Windows 8.

I successfully created an instance of hkpWorld, added an hkpRigidbody instance with hkpSphereShape.

The class representing the sphere object has:

hkpRigidBody m_RigidBody;  // Rigidbody
D3DXMATRIX m_Transform;    // Rendering matrix

Judging from the values of m_RigidBody->getPosition(), the simulation is running without problem.
So now obviously I want to render the sphere according to its position and orientation calculated by havok.

This is how I tried to extract the matrix for rendering:

const hkTransform& t = m_RigidBody->getTransform();
t.get4x4ColumnMajor(&m_Transform._11);

Then I happily ran the program, which would break in get4x4ColumnMajor and give me this message through my error report function:

C:\NightlyJobs\09-07-Sun-01\Source\Common/Base/Math/Vector/Sse/hkSseVector4.inl( 1831): [0x64211C2F] Assert: pointer must be aligned for SIMD.

I took this to mean that the matrix had to be 16-byte aligned, so I changed

D3DXMATRIX m_Transform;

to

D3DXMATRIXA16 m_Transform;

This time, the problem is still there but isn't 100% reproducible.
Sometimes it runs without problem, sometimes get4x4ColumnMajor fails with above message.

Changing the matrix declaration to

_declspec(align(16)) D3DXMATRIX m_Transform;

did not help either.

So, to summarize my question:

  • How would I go about extracting the matrix suitable for rendering with DirectX9?
  • Why do D3DXMATRIXA16 and _declspec(align(16)) seem to be inconsistent about being 16-byte aligned or not, every time I run the program ?
\$\endgroup\$
2
\$\begingroup\$

The main thing to remember is that _declspec(align(16)) only affects the struct/class layout, is respected for local or global variables, but has no affect on heap allocated memory.

In other words, it doesn't matter if the member variable of a class is marked with alignment if the class is allocated with new. Heap allocations by default with x86 (32-bit) are only 8-byte aligned, so you have a 50/50 shot of getting the required alignment that way. By default x64 native (64-bit) alignment is 16-byte.

Otherwise you need to make use of _aligned_malloc to get other alignment behavior from heap allocation. See MSDN for some more notes on this.

\$\endgroup\$
  • \$\begingroup\$ Thank you! I'm looking into _aligned_malloc you suggested, along with placement new :) \$\endgroup\$ – JamesAMD Jun 28 '15 at 8:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.