Moving to DirectXMath

Started by
10 comments, last by cozzie 9 years, 11 months ago
Hi,
I'm at the point where my codebase is growing larger and larger.
Since I'm still on dx9 and plan to move to / also support dx11, I'm thinking about moving from using d3dx to directxmath. Especially because I'm expanding my codebase with quite some math related stuff (collisions and intersections).

My question is basically what your advice would be, pro's and cons
(will directxmath work fine both with dx9 and 11? Etc)

Ps: for mesh usage and loading for now I'll stick to d3dxmesh, will change that later on. Above I'm aiming at basically ALL other d3dx usage in my engine.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

DirectXMath is not directly related to Direct3D/DXGI/WDDM stuffs, so you can use it with both DX9 and DX11, work with both X86 (IA32/SSE/SSE2/x64) and ARM (with ARM NEON support).

It is pretty easy to use, you only need to pay attention to data alignment of vector and matrix structures (you can disable the alignment requirement if you want with the _XM_NO_INTRINSICS_ macro).

On MSDN library you can find a pretty decent programming guide (with migration notes from D3DXMath and compatibility tables with D3DDECLTYPE, D3DFORMAT and DXGI_FORMAT).

The reference guide is pretty decent too, however you had to pay attention if you are using the RH coordinate system since some function without the proper coordinate system suffix need some attention (like the function involving axis... see the "remark" paragraph of related reference guide).

On directx sdk blog you can find some additional x86 SIMD extensions (SSE3/3S/4./4.1, AVX, FMA3/4, F16C...), they are linked somewhere on msdn library too.

DirectX Tool Kit has a DirectXMath wrapper too if you find it too much complicated.

"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/

(you can disable the alignment requirement if you want with the _XM_NO_INTRINSICS_ MAXRO).


There is no good reason to do this. XMVECTOR is _not_ meant for storing in general heap-allocated objects. It's for doing computations in local variables or special-purpose buffers. Use XMFLOAT2/3/4 for storing data in heap-allocated objects. Using strict alignment is a performance win but not at all mandatory if the DirectXMath library if used correctly.

Sean Middleditch – Game Systems Engineer – Join my team!

(you can disable the alignment requirement if you want with the _XM_NO_INTRINSICS_ MAXRO).


There is no good reason to do this. XMVECTOR is _not_ meant for storing in general heap-allocated objects. It's for doing computations in local variables or special-purpose buffers. Use XMFLOAT2/3/4 for storing data in heap-allocated objects. Using strict alignment is a performance win but not at all mandatory if the DirectXMath library if used correctly.

A good reason could be immediately starting using DirectXMath and become familiar with it, avoiding awkward alignments (like _aligned_mallc plus placement new) if you planned to write your own custom allocator (maybe with different platforms-specific intrinsics) but you don't have it yet ready. When your custom allocator is done and it's ready to use, you will just need to remove that macro.

"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/
Thanks. I'll probably move on to using directxmath asap.
When I read stuff about intrinsics, macro's etc., honestly I'm not connected.

Maybe I'm thinking too simple, but I believe these are the main things I have to do
- replace all class members of type D3DXVECTOR3 by XMFLOAT3's
- do the same for local D3DXVECTOR3's, which are created on the stack/ within scope of (member) functions
- do the above again, but for D3DXMATRIX to XMFLOAT4X4
- remove all includes of d3dx9(d).h, except in my mesh class header and cpp file
- compile and replace all uses d3dxfunctions by the directxmath replacement, throughout my codebase

Ofcourse I'll run into some minor bumps, but I believe this should be it.
For now I don't see reasons to use XMVECTOR or XMMATRIX instead, based on the MSDN reference I read. I currently also don't use the D3DX.....16 types, for alignment, because I don't have specific reasons to do so (no pre-optimizations wasting time and increasing future risks).

But... If I'm overseeing something, please tell me

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

You've pretty much covered a lot. I recently switched from DX9 to D3D11. I've converted quite a few classes using just the method you described.

A couple of times I did a search/replace-all in a file for the classes you named and hit the compile key to let VS locate needed corrections. You will need to use XMVECTOR and XMMATRIX for calcs but you'll pick that up pretty quickly. E.g.,


D3DXMATRIX mat1, mat2, mat3;
mat3 = mat1 * mat2;

becomes


XMFLOAT4X4 mat1, mat2, mat3;
XMStoreFloat4x4(&mat3, XMMatrixMultiply(XMLoadFloat4x4(&mat1),XMLoadFloat4x4(&mat2));

That will come pretty quickly to you, I believe.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Thanks. I'll probably move on to using directxmath asap.
When I read stuff about intrinsics, macro's etc., honestly I'm not connected.

Maybe I'm thinking too simple, but I believe these are the main things I have to do
- replace all class members of type D3DXVECTOR3 by XMFLOAT3's
- do the same for local D3DXVECTOR3's, which are created on the stack/ within scope of (member) functions
- do the above again, but for D3DXMATRIX to XMFLOAT4X4
- remove all includes of d3dx9(d).h, except in my mesh class header and cpp file
- compile and replace all uses d3dxfunctions by the directxmath replacement, throughout my codebase

Ofcourse I'll run into some minor bumps, but I believe this should be it.
For now I don't see reasons to use XMVECTOR or XMMATRIX instead, based on the MSDN reference I read. I currently also don't use the D3DX.....16 types, for alignment, because I don't have specific reasons to do so (no pre-optimizations wasting time and increasing future risks).

But... If I'm overseeing something, please tell me

XMFLOAT* structures don't require any particular alignment and they are meant to be used for simple tasks and getting/settings data.

XMVECTOR and XMMATRIX take advantage of CPU SIMD so they are meant to be used for computation and most useful DirectXMath function need and use XMVECTOR and XMMATRIX.

They require 16-byte alignment in order to use CPU SIMD extensions like SSE2 and ARM NEON. For automatic allocation (data and stack) you only need to add the /Zp16 compiler flag, for dynamic allocation you need to manually it manually (like _aligned_malloc + placement new) or to write your own custom allocator.

If 16-byte alignment is a problem for you or a pre-optimization wasting time just declare the _XM_NO_INTRINSICS_ macro, and everything will run fine.

Here you can find a direct D3DX-DirectXMath comparison and migration guide: http://msdn.microsoft.com/en-us/library/windows/desktop/ff729728(v=vs.85).aspx
"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/
Thanks. I've read the programming guide on MSDN.
There are some blanks for me. Are these conclusions correct:

- my goal is to make advantage of computation advantages (SSE intrinsics etc.)
- having a good balance, without having to use macro's or manual alignment code

I'll do this by:
- making class members of the types XMFLOATx and XMFLOATxXx
(for alignment reasons)
- for local variables in scope of functions I use XMVECTOR and XMMATRIX types, to take advantage of better computation (SSE etc.) without casting
-- when I need to use, either read or write to the class members of XMFLOAT... type, I always have to cast them to XMVECTOR/XMMATRIX types, when I want to use the DirectXMath functions. I probably also need to "cast" the results back into the class members

This sounds doable.

Till now I always used D3DX and build up a code base for frustum culling, bounding volume checks (intersection/ collision) etc. Besides the math I've learned doing this, I'm thinking about using the functions that do the same coming from the DirectXMath library. What do you think?

Another assumption I have to check, is that I can pass both XMFLOAT (class members in my case) as XMVECTOR/MATRIX type to set shader constants (for now with d3d9, later on d3d11). Now I think of it, I also have to find a solution when not using the d3dx effect framework anymore. Probably compiling the PS and VS manually. The good thing is that I don't set any states through my effects (I use my own state manager for that, through my code).

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

- my goal is to make advantage of computation advantages (SSE intrinsics etc.)

Then you need 16-byte aligment.

- having a good balance, without having to use macro's or manual alignment code

Then you need to define and code your own allocator.

- making class members of the types XMFLOATx and XMFLOATxXx
(for alignment reasons)

XMFLOATx and XMFLOAtxXx don't need 16-byte aligment.

- for local variables in scope of functions I use XMVECTOR and XMMATRIX types, to take advantage of better computation (SSE etc.) without casting

Remember that /Zp16 must be used setted, you can find the option in the C++ /Code generation tab in the project proprieties.

-- when I need to use, either read or write to the class members of XMFLOAT... type, I always have to cast them to XMVECTOR/XMMATRIX types, when I want to use the DirectXMath functions. I probably also need to "cast" the results back into the class members

DirectXMath provides loading and storing function for that : )

Till now I always used D3DX and build up a code base for frustum culling, bounding volume checks (intersection/ collision) etc. Besides the math I've learned doing this, I'm thinking about using the functions that do the same coming from the DirectXMath library. What do you think?

Aside from data alignment, DirectXMath is a natural evolution of D3DX, you should not having particular problem to convert the code.

Another assumption I have to check, is that I can pass both XMFLOAT (class members in my case) as XMVECTOR/MATRIX type to set shader constants (for now with d3d9, later on d3d11). Now I think of it, I also have to find a solution when not using the d3dx effect framework anymore. Probably compiling the PS and VS manually. The good thing is that I don't set any states through my effects (I use my own state manager for that, through my code).

Dunno if XMVECTOR could be passed directly to shaders(I always used XMFLOAT* for getting and settings data), however XMMATRIX could bepassed as D3D11_MAPPED_SUBRESOURCE.pData.
"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/


Remember that /Zp16 must be used setted

You don't need /Zp16 at all. The vector types are already set up with __declspec(align(16)) so they will get 16 byte aligned as local/global/static variables without any need for compiler flags. The only time you need to worry about alignment is on heap allocated data.

http://blogs.msdn.com/b/oldnewthing/archive/2007/12/27/6873648.aspx

This topic is closed to new replies.

Advertisement