Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/common/gsvector.h
4223 views
1
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
//
5
// Lightweight wrapper over native SIMD types for cross-platform vector code.
6
//
7
8
#pragma once
9
10
#include "common/intrin.h"
11
12
#if defined(CPU_ARCH_SSE)
13
#include "common/gsvector_sse.h"
14
#elif defined(CPU_ARCH_NEON)
15
#include "common/gsvector_neon.h"
16
#else
17
#include "common/gsvector_nosimd.h"
18
#endif
19
20
class GSMatrix2x2
21
{
22
public:
23
GSMatrix2x2() = default;
24
GSMatrix2x2(float e00, float e01, float e10, float e11);
25
26
GSMatrix2x2 operator*(const GSMatrix2x2& m) const;
27
28
GSVector2 operator*(const GSVector2& v) const;
29
30
static GSMatrix2x2 Identity();
31
static GSMatrix2x2 Rotation(float angle_in_radians);
32
33
GSVector2 row(size_t i) const;
34
GSVector2 col(size_t i) const;
35
36
void store(void* m);
37
38
alignas(8) float E[2][2];
39
};
40
41
class alignas(VECTOR_ALIGNMENT) GSMatrix4x4
42
{
43
public:
44
constexpr GSMatrix4x4() = default;
45
constexpr GSMatrix4x4(float e00, float e01, float e02, float e03, float e10, float e11, float e12, float e13,
46
float e20, float e21, float e22, float e23, float e30, float e31, float e32, float e33)
47
{
48
E[0][0] = e00;
49
E[0][1] = e01;
50
E[0][2] = e02;
51
E[0][3] = e03;
52
E[1][0] = e10;
53
E[1][1] = e11;
54
E[1][2] = e12;
55
E[1][3] = e13;
56
E[2][0] = e20;
57
E[2][1] = e21;
58
E[2][2] = e22;
59
E[2][3] = e23;
60
E[3][0] = e30;
61
E[3][1] = e31;
62
E[3][2] = e32;
63
E[3][3] = e33;
64
}
65
66
constexpr GSMatrix4x4(const GSMatrix2x2& m)
67
{
68
E[0][0] = m.E[0][0];
69
E[0][1] = m.E[0][1];
70
E[0][2] = 0.0f;
71
E[0][3] = 0.0f;
72
E[1][0] = m.E[1][0];
73
E[1][1] = m.E[1][1];
74
E[1][2] = 0.0f;
75
E[1][3] = 0.0f;
76
E[2][0] = 0.0f;
77
E[2][1] = 0.0f;
78
E[2][2] = 1.0f;
79
E[2][3] = 0.0f;
80
E[3][0] = 0.0f;
81
E[3][1] = 0.0f;
82
E[3][2] = 0.0f;
83
E[3][3] = 1.0f;
84
}
85
86
GSMatrix4x4 operator*(const GSMatrix4x4& m) const;
87
GSMatrix4x4& operator*=(const GSMatrix4x4& m);
88
89
GSVector4 operator*(const GSVector4& v) const
90
{
91
return GSVector4(row(0).dot(v), row(1).dot(v), row(2).dot(v), row(3).dot(v));
92
}
93
94
static constexpr GSMatrix4x4 Identity()
95
{
96
return GSMatrix4x4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
97
}
98
99
static GSMatrix4x4 RotationX(float angle_in_radians);
100
static GSMatrix4x4 RotationY(float angle_in_radians);
101
static GSMatrix4x4 RotationZ(float angle_in_radians);
102
static GSMatrix4x4 Translation(float x, float y, float z);
103
104
static GSMatrix4x4 OffCenterOrthographicProjection(float left, float top, float right, float bottom, float zNear,
105
float zFar);
106
static GSMatrix4x4 OffCenterOrthographicProjection(float width, float height, float zNear, float zFar);
107
108
GSVector4 row(size_t i) const { return GSVector4::load<true>(&E[i][0]); }
109
GSVector4 col(size_t i) const { return GSVector4(E[0][i], E[1][i], E[2][i], E[3][i]); }
110
111
void set_row(size_t i, GSVector4 row) { GSVector4::store<true>(&E[i][0], row); }
112
void set_col(size_t i, GSVector4 col)
113
{
114
E[0][i] = col.x;
115
E[1][i] = col.y;
116
E[2][i] = col.z;
117
E[3][i] = col.w;
118
}
119
120
GSMatrix4x4 invert() const;
121
122
void store(void* m);
123
124
float E[4][4];
125
};
126
127