xref: /aosp_15_r20/external/skia/resources/sksl/folding/MatrixScalarNoOpFolding.rts (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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