DirectX::XMMATRIX ошибка C2719: __declspec(align('16')) не будет выровнен

Итак, я работаю над своей собственной платформой DirectX. Все учебные пособия по созданию инфраструктуры DirectX устарели и используют устаревшие материалы, поэтому я просто создал свою собственную, хотя я кое-что взял из старых учебников и обновил их для работы с новым Windows 8.1 SDK и здесь возникает проблема, я получаю ошибки с XMMATRIX оригинальный код использует 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

это строка 33 из S_SHADER.h:

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

это строка 40 из S_SHADER.h:

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

и это строка 42 из S_SHADER.cpp:

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

на самом деле 41 имеет весь код и 42 имеет только открытые скобки, в любом случае, что я делаю не так?

РЕДАКТИРОВАТЬ: не думаю, что это поможет, но у меня есть Windows 7 64-битный компьютер с Visual Studio 2013

1 ответ

Решение

Это оказывается довольно сложным и рассматривается в MSDN.

Короткий ответ: вам нужно использовать дружественные к соглашению о вызовах typedef, которые работают с различными комбинациями x86 __fastcall, x64 __fastcall, ARM __fastcall и новой VS 2013 x86/x64 __vectorcall.

"Идеальное" решение:

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

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

Ваша оригинальная версия на самом деле будет компилироваться для x64 native, но каждый XMMATRIX помещается в стек и не передается "в регистр". x64 native гарантирует 16-байтовое выравнивание для переменных стека. Win32 и ARM нет.

Для x86 и x64 VS 2013 поддерживает новое соглашение о вызовах "__vectorcall", которое может передавать первые шесть (6) значений __m128 в регистр, включая гетерогенные векторные агрегаты (HVA), такие как XMMATRIX. Тем не менее, все, что не помещается в регистр, должно передаваться по "константной ссылке", а не по "значению".

Для VS 2012 и ниже, x86 __fastcall передает первые три (3) значения __m128 в регистр, но не может передавать HVA в регистр. Остальная часть должна передаваться по "константной ссылке", а не по "значению" из-за естественного выравнивания переменных стека.

Для VS 2012 и ниже x64 __fastcall никогда не передает значения __m128 в регистр. Хотя естественное выравнивание стека позволяет XMVECTOR и XMMATRIX передаваться по "значению" как копия в стеке, скорее всего, вместо этого будет более эффективно передавать по "константной ссылке".

Для ARM __fastcall передает первые четыре (4) значения __n128 в регистр и поддерживает HVA. В этом случае это будет один XMMATRIX.

Следовательно DirectXMath соглашения об использовании FXMVECTOR, GXMVECTOR, HXMVECTOR, CXMVECTOR, FXMMATRIX, а также CXMMATRIX для параметров, а не с помощью XMVECTOR или же XMMATRIX непосредственно. Сначала это может быть немного сложным, но поскольку компилятор жалуется, как вы видели в Win32, вы можете решать необычные или сложные случаи с небольшой пробой и (компиляцией) ошибкой.

С другой стороны, вы можете не беспокоиться об "оптимальном" поведении передачи регистров векторных и матричных значений, а просто выбрать что-то простое, например:

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

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

Это должно хорошо работать на всех архитектурах и соглашениях о вызовах.

Другие вопросы по тегам