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