1uniform float2x2 testMatrix2x2; 2uniform float3x3 testMatrix3x3; 3uniform float4 testInputs; 4uniform half4 colorRed, colorGreen; 5uniform half unknownInput; 6 7bool test_no_op_scalar_X_mat2() { 8 float2x2 m, mm; 9 const float2x2 z = float2x2(0.0); 10 11 // Test meaningful matrix X no-op scalar. 12 m = testMatrix2x2 * 1; 13 m = 1 * testMatrix2x2; 14 m *= 1; 15 if (m != testMatrix2x2) return false; 16 17 m = m / 1; 18 m /= 1; 19 if (m != testMatrix2x2) return false; 20 21 m = m + 0; 22 m = 0 + m; 23 m += 0; 24 if (m != testMatrix2x2) return false; 25 26 m = m - 0; 27 m = 0 - m; // negates 28 m -= 0; 29 if (m != -testMatrix2x2) return false; 30 31 mm = m * 0; 32 mm = 0 * m; 33 return mm == z; 34} 35 36bool test_no_op_scalar_X_mat3() { 37 float3x3 m, mm; 38 const float3x3 z = float3x3(0.0); 39 40 // Test meaningful matrix X no-op scalar. 41 m = testMatrix3x3 * 1; 42 m = 1 * testMatrix3x3; 43 m *= 1; 44 if (m != testMatrix3x3) return false; 45 46 m = m / 1; 47 m /= 1; 48 if (m != testMatrix3x3) return false; 49 50 m = m + 0; 51 m = 0 + m; 52 m += 0; 53 if (m != testMatrix3x3) return false; 54 55 m = m - 0; 56 m = 0 - m; // negates 57 m -= 0; 58 if (m != -testMatrix3x3) return false; 59 60 mm = m * 0; 61 mm = 0 * m; 62 return mm == z; 63} 64 65bool test_no_op_scalar_X_mat4() { 66 float4x4 testMatrix4x4 = float4x4(testInputs, testInputs, testInputs, testInputs); 67 float4x4 m, mm; 68 const float4x4 z = float4x4(0.0); 69 70 // Test meaningful matrix X no-op scalar. 71 m = testMatrix4x4 * 1; 72 m = 1 * testMatrix4x4; 73 m *= 1; 74 if (m != testMatrix4x4) return false; 75 76 m = m / 1; 77 m /= 1; 78 if (m != testMatrix4x4) return false; 79 80 m = m + 0; 81 m = 0 + m; 82 m += 0; 83 if (m != testMatrix4x4) return false; 84 85 m = m - 0; 86 m = 0 - m; // negates 87 m -= 0; 88 if (m != -testMatrix4x4) return false; 89 90 mm = m * 0; 91 mm = 0 * m; 92 return mm == z; 93} 94 95bool test_no_op_mat2_X_scalar() { 96 float2x2 m, mm; 97 const float2x2 i = float2x2(1.0); 98 const float2x2 z = float2x2(0.0); 99 const float2x2 s = float2x2(float4(1.0)); 100 float scalar = testInputs.x; 101 102 // These operations can be optimized, because multiplying a scalar across an identity matrix 103 // is conceptually the same as passing a scalar into the diagonal-matrix constructor. 104 m = scalar * i; 105 m = i * scalar; 106 if (m != float2x2(scalar)) return false; 107 108 // These operations are left alone, as they splat the scalar across the matrix. 109 m = scalar / s; 110 if (m != float2x2(scalar, scalar, scalar, scalar)) return false; 111 112 m = scalar + z; 113 m = z + scalar; 114 if (m != float2x2(scalar, scalar, scalar, scalar)) return false; 115 116 m = scalar - z; 117 m = z - scalar; // splats `-scalar` across the matrix 118 if (m != -float2x2(scalar, scalar, scalar, scalar)) return false; 119 120 mm = scalar * z; 121 mm = z * scalar; 122 return mm == z; 123} 124 125bool test_no_op_mat3_X_scalar() { 126 float3x3 m, mm; 127 const float3x3 i = float3x3(1.0); 128 const float3x3 z = float3x3(0.0); 129 const float3x3 s = float3x3(float3(1.0), float3(1.0), float3(1.0)); 130 float scalar = testInputs.x; 131 float3 scalar3 = scalar.xxx; 132 133 // These operations can be optimized, because multiplying a scalar across an identity matrix 134 // is conceptually the same as passing a scalar into the diagonal-matrix constructor. 135 m = scalar * i; 136 m = i * scalar; 137 if (m != float3x3(scalar)) return false; 138 139 // These operations are left alone, as they splat the scalar across the matrix. 140 m = scalar / s; 141 if (m != float3x3(scalar3, scalar3, scalar3)) return false; 142 143 m = scalar + z; 144 m = z + scalar; 145 if (m != float3x3(scalar3, scalar3, scalar3)) return false; 146 147 m = scalar - z; 148 m = z - scalar; // splats `-scalar` across the matrix 149 if (m != -float3x3(scalar3, scalar3, scalar3)) return false; 150 151 mm = scalar * z; 152 mm = z * scalar; 153 return mm == z; 154} 155 156bool test_no_op_mat4_X_scalar() { 157 float4x4 m, mm; 158 const float4x4 i = float4x4(1.0); 159 const float4x4 z = float4x4(0.0); 160 const float4x4 s = float4x4(float4(1.0), float4(1.0), float4(1.0), float4(1.0)); 161 float scalar = testInputs.x; 162 float4 scalar4 = scalar.xxxx; 163 164 // These operations can be optimized, because multiplying a scalar across an identity matrix 165 // is conceptually the same as passing a scalar into the diagonal-matrix constructor. 166 m = scalar * i; 167 m = i * scalar; 168 if (m != float4x4(scalar)) return false; 169 170 // These operations are left alone, as they splat the scalar across the matrix. 171 m = scalar / s; 172 if (m != float4x4(scalar4, scalar4, scalar4, scalar4)) return false; 173 174 m = scalar + z; 175 m = z + scalar; 176 if (m != float4x4(scalar4, scalar4, scalar4, scalar4)) return false; 177 178 m = scalar - z; 179 m = z - scalar; // splats `-scalar` across the matrix 180 if (m != -float4x4(scalar4, scalar4, scalar4, scalar4)) return false; 181 182 mm = scalar * z; 183 mm = z * scalar; 184 return mm == z; 185} 186 187half4 main(float2 coords) { 188 return test_no_op_scalar_X_mat2() && 189 test_no_op_scalar_X_mat3() && 190 test_no_op_scalar_X_mat4() && 191 test_no_op_mat2_X_scalar() && 192 test_no_op_mat3_X_scalar() && 193 test_no_op_mat4_X_scalar() ? colorGreen : colorRed; 194} 195