result = vml (matrix[0], vector);
result = vmla (result, matrix[1], vector);
result = vmla (result, matrix[2], vector);
result = vmla (result, matrix[3], vector);
Эта последовательность не сработает. Проблема в том, что компонент x накапливает только x, модулированный строками матрицы, и может быть выражен как:
result.x = vector.x * (matrix[0][0] + matrix[1][0] + matrix[2][0] + matrix[3][0]);
...
Правильная последовательность будет:
result = vml (matrix[0], vector.xxxx);
result = vmla(result, matrix[1], vector.yyyy);
...
NEON и SSE не имеют встроенного выбора для полей (для этого потребуется 8 битов в кодировке команд на каждый векторный регистр). Например, GLSL / HLSL имеет такие возможности, поэтому большинство графических процессоров также имеют.
Альтернативный способ добиться этого будет:
result.x = dp4(vector, matrix[0]);
result.y = dp4(vector, matrix[1]);
... // и, конечно, матрица будет транспонирована для этого, чтобы получить тот же результат
Последовательность mul, madd, madd, madd обычно предпочтительна, так как она не требует маски записи для полей целевого регистра.
В противном случае код выглядит хорошо. =)