xref: /aosp_15_r20/external/skia/tests/sksl/intrinsics/Inverse.metal (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1#include <metal_stdlib>
2#include <simd/simd.h>
3#ifdef __clang__
4#pragma clang diagnostic ignored "-Wall"
5#endif
6using namespace metal;
7struct Uniforms {
8    half4 colorGreen;
9    half4 colorRed;
10};
11struct Inputs {
12};
13struct Outputs {
14    half4 sk_FragColor [[color(0)]];
15};
16
17thread bool operator==(const float2x2 left, const float2x2 right);
18thread bool operator!=(const float2x2 left, const float2x2 right);
19
20thread bool operator==(const float3x3 left, const float3x3 right);
21thread bool operator!=(const float3x3 left, const float3x3 right);
22
23thread bool operator==(const float4x4 left, const float4x4 right);
24thread bool operator!=(const float4x4 left, const float4x4 right);
25thread bool operator==(const float2x2 left, const float2x2 right) {
26    return all(left[0] == right[0]) &&
27           all(left[1] == right[1]);
28}
29thread bool operator!=(const float2x2 left, const float2x2 right) {
30    return !(left == right);
31}
32thread bool operator==(const float3x3 left, const float3x3 right) {
33    return all(left[0] == right[0]) &&
34           all(left[1] == right[1]) &&
35           all(left[2] == right[2]);
36}
37thread bool operator!=(const float3x3 left, const float3x3 right) {
38    return !(left == right);
39}
40thread bool operator==(const float4x4 left, const float4x4 right) {
41    return all(left[0] == right[0]) &&
42           all(left[1] == right[1]) &&
43           all(left[2] == right[2]) &&
44           all(left[3] == right[3]);
45}
46thread bool operator!=(const float4x4 left, const float4x4 right) {
47    return !(left == right);
48}
49
50template <typename T>
51matrix<T, 3, 3> mat3_inverse(matrix<T, 3, 3> m) {
52T
53 a00 = m[0].x, a01 = m[0].y, a02 = m[0].z,
54 a10 = m[1].x, a11 = m[1].y, a12 = m[1].z,
55 a20 = m[2].x, a21 = m[2].y, a22 = m[2].z,
56 b01 =  a22*a11 - a12*a21,
57 b11 = -a22*a10 + a12*a20,
58 b21 =  a21*a10 - a11*a20,
59 det = a00*b01 + a01*b11 + a02*b21;
60return matrix<T, 3, 3>(
61 b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),
62 b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),
63 b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) * (1/det);
64}
65
66template <typename T>
67matrix<T, 2, 2> mat2_inverse(matrix<T, 2, 2> m) {
68return matrix<T, 2, 2>(m[1].y, -m[0].y, -m[1].x, m[0].x) * (1/determinant(m));
69}
70
71template <typename T>
72matrix<T, 4, 4> mat4_inverse(matrix<T, 4, 4> m) {
73T
74 a00 = m[0].x, a01 = m[0].y, a02 = m[0].z, a03 = m[0].w,
75 a10 = m[1].x, a11 = m[1].y, a12 = m[1].z, a13 = m[1].w,
76 a20 = m[2].x, a21 = m[2].y, a22 = m[2].z, a23 = m[2].w,
77 a30 = m[3].x, a31 = m[3].y, a32 = m[3].z, a33 = m[3].w,
78 b00 = a00*a11 - a01*a10,
79 b01 = a00*a12 - a02*a10,
80 b02 = a00*a13 - a03*a10,
81 b03 = a01*a12 - a02*a11,
82 b04 = a01*a13 - a03*a11,
83 b05 = a02*a13 - a03*a12,
84 b06 = a20*a31 - a21*a30,
85 b07 = a20*a32 - a22*a30,
86 b08 = a20*a33 - a23*a30,
87 b09 = a21*a32 - a22*a31,
88 b10 = a21*a33 - a23*a31,
89 b11 = a22*a33 - a23*a32,
90 det = b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06;
91return matrix<T, 4, 4>(
92 a11*b11 - a12*b10 + a13*b09,
93 a02*b10 - a01*b11 - a03*b09,
94 a31*b05 - a32*b04 + a33*b03,
95 a22*b04 - a21*b05 - a23*b03,
96 a12*b08 - a10*b11 - a13*b07,
97 a00*b11 - a02*b08 + a03*b07,
98 a32*b02 - a30*b05 - a33*b01,
99 a20*b05 - a22*b02 + a23*b01,
100 a10*b10 - a11*b08 + a13*b06,
101 a01*b08 - a00*b10 - a03*b06,
102 a30*b04 - a31*b02 + a33*b00,
103 a21*b02 - a20*b04 - a23*b00,
104 a11*b07 - a10*b09 - a12*b06,
105 a00*b09 - a01*b07 + a02*b06,
106 a31*b01 - a30*b03 - a32*b00,
107 a20*b03 - a21*b01 + a22*b00) * (1/det);
108}
109fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
110    Outputs _out;
111    (void)_out;
112    const float2x2 matrix2x2 = float2x2(float2(1.0, 2.0), float2(3.0, 4.0));
113    float2x2 inv2x2 = float2x2(float2(-2.0, 1.0), float2(1.5, -0.5));
114    float3x3 inv3x3 = float3x3(float3(-24.0, 18.0, 5.0), float3(20.0, -15.0, -4.0), float3(-5.0, 4.0, 1.0));
115    float4x4 inv4x4 = float4x4(float4(-2.0, -0.5, 1.0, 0.5), float4(1.0, 0.5, 0.0, -0.5), float4(-8.0, -1.0, 2.0, 2.0), float4(3.0, 0.5, -1.0, -0.5));
116    float Zero = float(_uniforms.colorGreen.z);
117    _out.sk_FragColor = (((((float2x2(float2(-2.0, 1.0), float2(1.5, -0.5)) == inv2x2 && float3x3(float3(-24.0, 18.0, 5.0), float3(20.0, -15.0, -4.0), float3(-5.0, 4.0, 1.0)) == inv3x3) && float4x4(float4(-2.0, -0.5, 1.0, 0.5), float4(1.0, 0.5, 0.0, -0.5), float4(-8.0, -1.0, 2.0, 2.0), float4(3.0, 0.5, -1.0, -0.5)) == inv4x4) && mat3_inverse(float3x3(float3(1.0, 2.0, 3.0), float3(4.0, 5.0, 6.0), float3(7.0, 8.0, 9.0))) != inv3x3) && mat2_inverse(matrix2x2 + (float2x2(1.0, 1.0, 1.0, 1.0) * Zero)) == inv2x2) && mat3_inverse(float3x3(float3(1.0, 2.0, 3.0), float3(0.0, 1.0, 4.0), float3(5.0, 6.0, 0.0)) + (float3x3(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0) * Zero)) == inv3x3) && mat4_inverse(float4x4(float4(1.0, 0.0, 0.0, 1.0), float4(0.0, 2.0, 1.0, 2.0), float4(2.0, 1.0, 0.0, 1.0), float4(2.0, 0.0, 1.0, 4.0)) + (float4x4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0) * Zero)) == inv4x4 ? _uniforms.colorGreen : _uniforms.colorRed;
118    return _out;
119}
120