Итак, я работаю над своей собственной платформой 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
Это оказывается довольно сложным, и рассматривается MSDN.
Короткий ответ: вам нужно использовать дружественные к соглашению о вызовах typedefs, которые работают с различными комбинациями 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, но каждый 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&);
Это должно хорошо работать на всех архитектурах и соглашениях о вызовах.