2

Ok so im working on my own DirectX framework all tutorials about making a DirectX framework are old and use deprecated stuff so i just made my own one , though i took somethings from the old tutorials and updated them to work with the new Windows 8.1 SDK and here comes The problem , i get errors with XMMATRIX the original code uses D3DXMATRIX

(33): error C2719: 'unnamed-parameter': formal parameter with __declspec(align('16')) won't be aligned
(40): error C2719: 'unnamed-parameter': formal parameter with __declspec(align('16')) won't be aligned
(42): error C2719: 'worldMatrix': formal parameter with __declspec(align('16')) won't be aligned
(42): error C2719: 'viewMatrix': formal parameter with __declspec(align('16')) won't be aligned
(42): error C2719: 'projectionMatrix': formal parameter with __declspec(align('16')) won't be aligned

this is Line 33 from S_SHADER.h :

bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX);

this is line 40 from S_SHADER.h :

bool SetSHaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX);

and this is line 42 from S_SHADER.cpp :

41 - bool S_SHADER::Render(ID3D11DeviceContext* deviceContext, int indexCount, DirectX::XMMATRIX worldMatrix,  DirectX::XMMATRIX viewMatrix, DirectX::XMMATRIX projectionMatrix)
42 - {

actually 41 has all the code and 42 has only the open brackets , anyways what am i doing wrong ?

EDIT : dont think this will help but i have a windows 7 64 bit computer with visual studio 2013

1 Answers1

9

This turns out to be rather complicated, and is covered on MSDN.

The short answer is you need to use calling-convention friendly typedefs that work with the various combinations of x86 __fastcall, x64 __fastcall, ARM __fastcall, and the new VS 2013 x86/x64 __vectorcall.

The 'ideal' solution is:

bool XM_CALLCONV Render(ID3D11DeviceContext*, int, FXMMATRIX, CXMMATRIX, CXMMATRIX);

bool XM_CALLCONV SetSHaderParameters(ID3D11DeviceContext*, FXMMATRIX, CXMMATRIX, CXMMATRIX);

Your original version would actually compile for x64 native, but each XMMATRIX is pushed onto the stack and is not passed "in-register". x64 native guarantees 16-byte alignment for stack variables. Win32 and ARM do not.

For x86 and x64, VS 2013 supports a new calling convention "__vectorcall" which can pass the first six (6) __m128 values in register including Heterogeneous Vector Aggregates (HVAs) like XMMATRIX. However, anything that doesn't fit into register should be passed by 'const reference' rather than by 'value'.

For VS 2012 and below, x86 __fastcall passes the first three (3) __m128 values in register, but cannot pass HVAs in register. The remainder have to be passed by 'const reference' rather than by 'value' due to the natural alignment of stack variables.

For VS 2012 and below, x64 __fastcall never passes __m128 values in register. While the natural alignment of the stack allows XMVECTOR and XMMATRIX to be passed by 'value' as a copy on the stack, it's likely more efficient to pass by 'const reference' instead.

For ARM, __fastcall passes the first four (4) __n128 values in register, and supports HVA. In this case, that would be one XMMATRIX.

Hence DirectXMath's conventions of using FXMVECTOR, GXMVECTOR, HXMVECTOR, CXMVECTOR, FXMMATRIX, and CXMMATRIX for parameters rather than using XMVECTOR or XMMATRIX directly. This can be a little complicated at first, but since the compiler complains as you've seen with Win32, you can work out unusual or complicated cases with a little trial and (compiler) error.

Alternately, you can not worry about 'optimal' register passing behavior of vector and matrix values, and just opt for something simple like:

bool Render(ID3D11DeviceContext*, int, const XMMATRIX&, const XMMATRIX&, const XMMATRIX&);

bool SetSHaderParameters(ID3D11DeviceContext*, const XMMATRIX&, const XMMATRIX&, const XMMATRIX&);

This should work fine across all the architectures and calling-conventions.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • Thanks.. This Worked For The Two Functions , Theres No More Errors though What about the line 42 :\ –  Aug 14 '14 at 06:59
  • You need to update 42 to match the prototype you use for line 33. So if using the 'simple' solution, it should be ``bool S_SHADER::Render(ID3D11DeviceContext* deviceContext, int indexCount, DirectX::XMMATRIX& worldMatrix, DirectX::XMMATRIX& viewMatrix, DirectX::XMMATRIX& projectionMatrix`` – Chuck Walbourn Aug 14 '14 at 07:05
  • Yup thats what i did i added that XM_CALLCONV to the line 42 so it became bool XM_CALLCONV S_SHADER::Render(...... and it gave to Other Errors ( unresolved externals ) ill make an edit on the post –  Aug 14 '14 at 07:08
  • Then it should be: ``bool XM_CALLCONV S_SHADER::Render(ID3D11DeviceContext* deviceContext, int indexCount, FXMMATRIX worldMatrix, CXMMATRIX viewMatrix, CXMMATRIX projectionMatrix)``. – Chuck Walbourn Aug 14 '14 at 07:10
  • it Worked Thanks alot :)) i just didnt have those function declared thats why i got those unresolved externals U saved My Life :)) –  Aug 14 '14 at 07:21
  • 1
    Because I wrote [DirectXMath](http://blogs.msdn.com/b/chuckw/archive/2012/03/27/introducing-directxmath.aspx)... :) – Chuck Walbourn Aug 14 '14 at 07:25
  • 1
    Read the [MSDN Programming Guide](http://msdn.microsoft.com/en-us/library/windows/desktop/ee415571.aspx) from start to finish. It's not long, and contains a lot of recommendations. If you want a simpler to use math library, take a look at the [SimpleMath](http://blogs.msdn.com/b/shawnhar/archive/2013/01/08/simplemath-a-simplified-wrapper-for-directxmath.aspx) wrapper for DirectXMath which makes it less efficient, but more forgiving of issues like the calling convention. – Chuck Walbourn Aug 14 '14 at 18:30
  • Dang thanks a lot for the great post @ChuckWalbourn! Can be difficult to find clarifications like this. – RandyGaul Feb 19 '15 at 23:36