Vecmat 0.2.3
C math and linear algebra library for 2D/3D graphics, physics, and science.
Loading...
Searching...
No Matches
matrix4_ptr.c
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025-2026 Igal Alkon
2// SPDX-FileCopyrightText: 2026 ALKONTEK <git@alkontek.com>
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <immintrin.h>
6#include <string.h>
7#include <vecmat.h>
8
9#if defined(VECMAT_USE_F64)
10
11void mat4_mul_ptr_avx512(matrix4 *res, const matrix4 *a, const matrix4 *b)
12{
13 matrix4 tmp;
14 const __m256d a0 = _mm256_loadu_pd(&a->v[0]);
15 const __m256d a1 = _mm256_loadu_pd(&a->v[4]);
16 const __m256d a2 = _mm256_loadu_pd(&a->v[8]);
17 const __m256d a3 = _mm256_loadu_pd(&a->v[12]);
18 for (int c = 0; c < 4; c++) {
19 __m256d col = _mm256_mul_pd(a0, _mm256_set1_pd(b->v[c * 4 + 0]));
20 col = _mm256_fmadd_pd(a1, _mm256_set1_pd(b->v[c * 4 + 1]), col);
21 col = _mm256_fmadd_pd(a2, _mm256_set1_pd(b->v[c * 4 + 2]), col);
22 col = _mm256_fmadd_pd(a3, _mm256_set1_pd(b->v[c * 4 + 3]), col);
23 _mm256_storeu_pd(&tmp.v[c * 4], col);
24 }
25 memcpy(res->v, tmp.v, sizeof(tmp.v));
26}
27
29{
30 __m256d r0 = _mm256_loadu_pd(&m->v[0]);
31 __m256d r1 = _mm256_loadu_pd(&m->v[4]);
32 __m256d r2 = _mm256_loadu_pd(&m->v[8]);
33 __m256d r3 = _mm256_loadu_pd(&m->v[12]);
34
35 __m256d t0 = _mm256_unpacklo_pd(r0, r1);
36 __m256d t1 = _mm256_unpackhi_pd(r0, r1);
37 __m256d t2 = _mm256_unpacklo_pd(r2, r3);
38 __m256d t3 = _mm256_unpackhi_pd(r2, r3);
39
40 r0 = _mm256_permute2f128_pd(t0, t2, 0x20);
41 r1 = _mm256_permute2f128_pd(t1, t3, 0x20);
42 r2 = _mm256_permute2f128_pd(t0, t2, 0x31);
43 r3 = _mm256_permute2f128_pd(t1, t3, 0x31);
44
45 matrix4 tmp;
46 _mm256_storeu_pd(&tmp.v[0], r0);
47 _mm256_storeu_pd(&tmp.v[4], r1);
48 _mm256_storeu_pd(&tmp.v[8], r2);
49 _mm256_storeu_pd(&tmp.v[12], r3);
50 memcpy(res->v, tmp.v, sizeof(tmp.v));
51}
52
53void mat4_mul_vec4_ptr_avx512(vector4 *res, const matrix4 *m, const vector4 *v)
54{
55 __m256d r = _mm256_mul_pd(_mm256_loadu_pd(&m->v[0]), _mm256_set1_pd(v->x));
56 r = _mm256_fmadd_pd(_mm256_loadu_pd(&m->v[4]), _mm256_set1_pd(v->y), r);
57 r = _mm256_fmadd_pd(_mm256_loadu_pd(&m->v[8]), _mm256_set1_pd(v->z), r);
58 r = _mm256_fmadd_pd(_mm256_loadu_pd(&m->v[12]), _mm256_set1_pd(v->w), r);
59 _mm256_storeu_pd(res->v, r);
60}
61
62void mat4_mul_vec3_ptr_avx512(vector3 *res, const matrix4 *m, const vector3 *v, const vm_float_t w)
63{
64 __m256d r = _mm256_mul_pd(_mm256_loadu_pd(&m->v[0]), _mm256_set1_pd(v->x));
65 r = _mm256_fmadd_pd(_mm256_loadu_pd(&m->v[4]), _mm256_set1_pd(v->y), r);
66 r = _mm256_fmadd_pd(_mm256_loadu_pd(&m->v[8]), _mm256_set1_pd(v->z), r);
67 r = _mm256_fmadd_pd(_mm256_loadu_pd(&m->v[12]), _mm256_set1_pd(w), r);
68 double t[4];
69 _mm256_storeu_pd(t, r);
70 res->x = t[0];
71 res->y = t[1];
72 res->z = t[2];
73}
74
75#else /* float: one ZMM holds the whole matrix */
76
77void mat4_mul_ptr_avx512(matrix4 *res, const matrix4 *a, const matrix4 *b)
78{
79 const __m512 A = _mm512_loadu_ps(a->v);
80 const __m512 B = _mm512_loadu_ps(b->v);
81
82 /* C.col[j] += A.col[k] * B[k,j] for k = 0..3, all four columns at once */
83 __m512 acc = _mm512_mul_ps(
84 _mm512_permutexvar_ps(_mm512_setr_epi32(
85 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3), A),
86 _mm512_permutexvar_ps(_mm512_setr_epi32(
87 0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12), B));
88
89 acc = _mm512_fmadd_ps(
90 _mm512_permutexvar_ps(_mm512_setr_epi32(
91 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7), A),
92 _mm512_permutexvar_ps(_mm512_setr_epi32(
93 1, 1, 1, 1, 5, 5, 5, 5, 9, 9, 9, 9, 13, 13, 13, 13), B),
94 acc);
95
96 acc = _mm512_fmadd_ps(
97 _mm512_permutexvar_ps(_mm512_setr_epi32(
98 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11), A),
99 _mm512_permutexvar_ps(_mm512_setr_epi32(
100 2, 2, 2, 2, 6, 6, 6, 6, 10, 10, 10, 10, 14, 14, 14, 14), B),
101 acc);
102
103 acc = _mm512_fmadd_ps(
104 _mm512_permutexvar_ps(_mm512_setr_epi32(
105 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15), A),
106 _mm512_permutexvar_ps(_mm512_setr_epi32(
107 3, 3, 3, 3, 7, 7, 7, 7, 11, 11, 11, 11, 15, 15, 15, 15), B),
108 acc);
109
110 matrix4 tmp;
111 _mm512_storeu_ps(tmp.v, acc);
112 memcpy(res->v, tmp.v, sizeof(tmp.v));
113}
114
115void mat4_transpose_ptr_avx512(matrix4 *res, const matrix4 *m)
116{
117 const __m512 t = _mm512_permutexvar_ps(
118 _mm512_setr_epi32(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15),
119 _mm512_loadu_ps(m->v));
120 matrix4 tmp;
121 _mm512_storeu_ps(tmp.v, t);
122 memcpy(res->v, tmp.v, sizeof(tmp.v));
123}
124
125void mat4_mul_vec4_ptr_avx512(vector4 *res, const matrix4 *m, const vector4 *v)
126{
127 __m128 r = _mm_mul_ps(_mm_loadu_ps(&m->v[0]), _mm_set1_ps(v->x));
128 r = _mm_fmadd_ps(_mm_loadu_ps(&m->v[4]), _mm_set1_ps(v->y), r);
129 r = _mm_fmadd_ps(_mm_loadu_ps(&m->v[8]), _mm_set1_ps(v->z), r);
130 r = _mm_fmadd_ps(_mm_loadu_ps(&m->v[12]), _mm_set1_ps(v->w), r);
131 _mm_storeu_ps(res->v, r);
132}
133
134void mat4_mul_vec3_ptr_avx512(vector3 *res, const matrix4 *m, const vector3 *v, const vm_float_t w)
135{
136 __m128 r = _mm_mul_ps(_mm_loadu_ps(&m->v[0]), _mm_set1_ps(v->x));
137 r = _mm_fmadd_ps(_mm_loadu_ps(&m->v[4]), _mm_set1_ps(v->y), r);
138 r = _mm_fmadd_ps(_mm_loadu_ps(&m->v[8]), _mm_set1_ps(v->z), r);
139 r = _mm_fmadd_ps(_mm_loadu_ps(&m->v[12]), _mm_set1_ps(w), r);
140 float t[4];
141 _mm_storeu_ps(t, r);
142 res->x = t[0];
143 res->y = t[1];
144 res->z = t[2];
145}
146
147#endif
void mat4_mul_ptr_avx512(matrix4 *res, const matrix4 *a, const matrix4 *b)
Definition matrix4_ptr.c:11
void mat4_transpose_ptr_avx512(matrix4 *res, const matrix4 *m)
Definition matrix4_ptr.c:28
void mat4_mul_vec4_ptr_avx512(vector4 *res, const matrix4 *m, const vector4 *v)
Definition matrix4_ptr.c:53
void mat4_mul_vec3_ptr_avx512(vector3 *res, const matrix4 *m, const vector3 *v, const vm_float_t w)
Definition matrix4_ptr.c:62
vm_float_t v[VECMAT_MAT4_SIZE]
Definition vecmat.h:271
vm_float_t z
Definition vecmat.h:139
vm_float_t y
Definition vecmat.h:138
vm_float_t x
Definition vecmat.h:137
vm_float_t z
Definition vecmat.h:150
vm_float_t v[VECMAT_VEC4_SIZE]
Definition vecmat.h:153
vm_float_t x
Definition vecmat.h:148
vm_float_t y
Definition vecmat.h:149
vm_float_t w
Definition vecmat.h:151
double vm_float_t
Definition vecmat.h:79