Jump to content

  • Log In with Google      Sign In   
  • Create Account

Moving to DirectXMath


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 cozzie   Members   -  Reputation: 1611

Like
0Likes
Like

Posted 05 May 2014 - 01:38 PM

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.

Sponsor:

#2 Alessio1989   Members   -  Reputation: 2002

Like
0Likes
Like

Posted 05 May 2014 - 03:17 PM

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.


Edited by Alessio1989, 06 May 2014 - 08:34 AM.

"Software does not run in a magical fairy aether powered by the fevered dreams of CS PhDs"


#3 SeanMiddleditch   Members   -  Reputation: 5803

Like
0Likes
Like

Posted 05 May 2014 - 11:06 PM

(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.

#4 Alessio1989   Members   -  Reputation: 2002

Like
0Likes
Like

Posted 06 May 2014 - 08:44 AM

 

(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.


Edited by Alessio1989, 06 May 2014 - 08:45 AM.

"Software does not run in a magical fairy aether powered by the fevered dreams of CS PhDs"


#5 cozzie   Members   -  Reputation: 1611

Like
0Likes
Like

Posted 06 May 2014 - 01:48 PM

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

#6 Buckeye   Crossbones+   -  Reputation: 4918

Like
0Likes
Like

Posted 06 May 2014 - 02:02 PM

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.


#7 Alessio1989   Members   -  Reputation: 2002

Like
0Likes
Like

Posted 06 May 2014 - 02:22 PM

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

Edited by Alessio1989, 06 May 2014 - 02:26 PM.

"Software does not run in a magical fairy aether powered by the fevered dreams of CS PhDs"


#8 cozzie   Members   -  Reputation: 1611

Like
0Likes
Like

Posted 06 May 2014 - 02:49 PM

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).

#9 Alessio1989   Members   -  Reputation: 2002

Like
0Likes
Like

Posted 06 May 2014 - 03:10 PM

- 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.

Edited by Alessio1989, 06 May 2014 - 03:11 PM.

"Software does not run in a magical fairy aether powered by the fevered dreams of CS PhDs"


#10 Adam_42   Crossbones+   -  Reputation: 2506

Like
3Likes
Like

Posted 06 May 2014 - 05:29 PM


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



#11 Alessio1989   Members   -  Reputation: 2002

Like
1Likes
Like

Posted 06 May 2014 - 05:54 PM

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

 
XMMATRIX and opaque vectors (XMVECTORF32, XMVECTORI32, XMVECTORU8, XMVECTORU32) are defined with __declspec(align(16)) , but not XMVECTOR:
 
//------------------------------------------------------------------------------
// Vector intrinsic: Four 32 bit floating point components aligned on a 16 byte 
// boundary and mapped to hardware vector registers
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
typedef __m128 XMVECTOR;
#elif defined(_XM_ARM_NEON_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
typedef __n128 XMVECTOR;
#else
typedef __vector4 XMVECTOR;
#endif
EDIT: you're right  : = 0
 
__m128 is 16-byte aligned
typedef union __declspec(intrin_type) _CRT_ALIGN(16) __m128 {
     float               m128_f32[4];
     unsigned __int64    m128_u64[2];
     __int8              m128_i8[16];
     __int16             m128_i16[8];
     __int32             m128_i32[4];
     __int64             m128_i64[2];
     unsigned __int8     m128_u8[16];
     unsigned __int16    m128_u16[8];
     unsigned __int32    m128_u32[4];
 } __m128;
where _CRT_ALIGN(16) is an alias of the CRT

#define _CRT_ALIGN(x) __declspec(align(x))
nice to know that : p

Edited by Alessio1989, 06 May 2014 - 06:06 PM.

"Software does not run in a magical fairy aether powered by the fevered dreams of CS PhDs"


#12 cozzie   Members   -  Reputation: 1611

Like
0Likes
Like

Posted 07 May 2014 - 01:26 PM

Thanks guys, this should get me started.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS