• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#pragma clang diagnostic ignored "-Wmissing-prototypes"
2
3#include <metal_stdlib>
4#include <simd/simd.h>
5
6using namespace metal;
7
8struct UBO
9{
10    float4x4 uMVP;
11    float3 rotDeg;
12    float3 rotRad;
13    int2 bits;
14};
15
16struct main0_out
17{
18    float3 vNormal [[user(locn0)]];
19    float3 vRotDeg [[user(locn1)]];
20    float3 vRotRad [[user(locn2)]];
21    int2 vLSB [[user(locn3)]];
22    int2 vMSB [[user(locn4)]];
23    float4 gl_Position [[position]];
24};
25
26struct main0_in
27{
28    float4 aVertex [[attribute(0)]];
29    float3 aNormal [[attribute(1)]];
30};
31
32// Implementation of the GLSL radians() function
33template<typename T>
34inline T radians(T d)
35{
36    return d * T(0.01745329251);
37}
38
39// Implementation of the GLSL degrees() function
40template<typename T>
41inline T degrees(T r)
42{
43    return r * T(57.2957795131);
44}
45
46// Implementation of the GLSL findLSB() function
47template<typename T>
48inline T spvFindLSB(T x)
49{
50    return select(ctz(x), T(-1), x == T(0));
51}
52
53// Implementation of the signed GLSL findMSB() function
54template<typename T>
55inline T spvFindSMSB(T x)
56{
57    T v = select(x, T(-1) - x, x < T(0));
58    return select(clz(T(0)) - (clz(v) + T(1)), T(-1), v == T(0));
59}
60
61// Returns the determinant of a 2x2 matrix.
62static inline __attribute__((always_inline))
63float spvDet2x2(float a1, float a2, float b1, float b2)
64{
65    return a1 * b2 - b1 * a2;
66}
67
68// Returns the determinant of a 3x3 matrix.
69static inline __attribute__((always_inline))
70float spvDet3x3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
71{
72    return a1 * spvDet2x2(b2, b3, c2, c3) - b1 * spvDet2x2(a2, a3, c2, c3) + c1 * spvDet2x2(a2, a3, b2, b3);
73}
74
75// Returns the inverse of a matrix, by using the algorithm of calculating the classical
76// adjoint and dividing by the determinant. The contents of the matrix are changed.
77static inline __attribute__((always_inline))
78float4x4 spvInverse4x4(float4x4 m)
79{
80    float4x4 adj;	// The adjoint matrix (inverse after dividing by determinant)
81
82    // Create the transpose of the cofactors, as the classical adjoint of the matrix.
83    adj[0][0] =  spvDet3x3(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]);
84    adj[0][1] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]);
85    adj[0][2] =  spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], m[3][3]);
86    adj[0][3] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3]);
87
88    adj[1][0] = -spvDet3x3(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]);
89    adj[1][1] =  spvDet3x3(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]);
90    adj[1][2] = -spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], m[3][3]);
91    adj[1][3] =  spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3]);
92
93    adj[2][0] =  spvDet3x3(m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]);
94    adj[2][1] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]);
95    adj[2][2] =  spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
96    adj[2][3] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3]);
97
98    adj[3][0] = -spvDet3x3(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]);
99    adj[3][1] =  spvDet3x3(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]);
100    adj[3][2] = -spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], m[3][2]);
101    adj[3][3] =  spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2]);
102
103    // Calculate the determinant as a combination of the cofactors of the first row.
104    float det = (adj[0][0] * m[0][0]) + (adj[0][1] * m[1][0]) + (adj[0][2] * m[2][0]) + (adj[0][3] * m[3][0]);
105
106    // Divide the classical adjoint matrix by the determinant.
107    // If determinant is zero, matrix is not invertable, so leave it unchanged.
108    return (det != 0.0f) ? (adj * (1.0f / det)) : m;
109}
110
111vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _18 [[buffer(0)]])
112{
113    main0_out out = {};
114    out.gl_Position = spvInverse4x4(_18.uMVP) * in.aVertex;
115    out.vNormal = in.aNormal;
116    out.vRotDeg = degrees(_18.rotRad);
117    out.vRotRad = radians(_18.rotDeg);
118    out.vLSB = spvFindLSB(_18.bits);
119    out.vMSB = spvFindSMSB(_18.bits);
120    return out;
121}
122
123