xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fShaderMatrixTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Shader matrix arithmetic tests.
22*35238bceSAndroid Build Coastguard Worker  *
23*35238bceSAndroid Build Coastguard Worker  * Variables:
24*35238bceSAndroid Build Coastguard Worker  *  + operation
25*35238bceSAndroid Build Coastguard Worker  *    - mat OP mat
26*35238bceSAndroid Build Coastguard Worker  *    - mat OP vec
27*35238bceSAndroid Build Coastguard Worker  *    - vec OP mat
28*35238bceSAndroid Build Coastguard Worker  *    - mat OP scalar
29*35238bceSAndroid Build Coastguard Worker  *    - OP ( mat )
30*35238bceSAndroid Build Coastguard Worker  *    - vec OP vec
31*35238bceSAndroid Build Coastguard Worker  *    - OP mat
32*35238bceSAndroid Build Coastguard Worker  *  + matrix source
33*35238bceSAndroid Build Coastguard Worker  *    - constant (ctor)
34*35238bceSAndroid Build Coastguard Worker  *    - uniform
35*35238bceSAndroid Build Coastguard Worker  *    - vertex input
36*35238bceSAndroid Build Coastguard Worker  *    - fragment input
37*35238bceSAndroid Build Coastguard Worker  *  + other operand: always dynamic data?
38*35238bceSAndroid Build Coastguard Worker  *  + how to reduce to vec3?
39*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker #include "es3fShaderMatrixTests.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "glsShaderRenderCase.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "gluShaderUtil.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
45*35238bceSAndroid Build Coastguard Worker #include "tcuMatrix.hpp"
46*35238bceSAndroid Build Coastguard Worker #include "tcuMatrixUtil.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
48*35238bceSAndroid Build Coastguard Worker #include "deFloat16.h"
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
51*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker namespace deqp
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker namespace gles3
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker namespace Functional
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker 
60*35238bceSAndroid Build Coastguard Worker using std::string;
61*35238bceSAndroid Build Coastguard Worker using std::vector;
62*35238bceSAndroid Build Coastguard Worker using namespace glu;
63*35238bceSAndroid Build Coastguard Worker using namespace deqp::gls;
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker using tcu::Mat2;
66*35238bceSAndroid Build Coastguard Worker using tcu::Mat2x3;
67*35238bceSAndroid Build Coastguard Worker using tcu::Mat2x4;
68*35238bceSAndroid Build Coastguard Worker using tcu::Mat3;
69*35238bceSAndroid Build Coastguard Worker using tcu::Mat3x2;
70*35238bceSAndroid Build Coastguard Worker using tcu::Mat3x4;
71*35238bceSAndroid Build Coastguard Worker using tcu::Mat4;
72*35238bceSAndroid Build Coastguard Worker using tcu::Mat4x2;
73*35238bceSAndroid Build Coastguard Worker using tcu::Mat4x3;
74*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
75*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
76*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker // Uniform / constant values for tests.
79*35238bceSAndroid Build Coastguard Worker // \note Input1 should not contain 0 components as it is used as divisor in div cases.
80*35238bceSAndroid Build Coastguard Worker // \todo [2012-02-14 pyry] Make these dynamic.
81*35238bceSAndroid Build Coastguard Worker static const float s_constInFloat[2] = {0.5f, -0.2f};
82*35238bceSAndroid Build Coastguard Worker static const Vec2 s_constInVec2[2]   = {Vec2(1.2f, 0.5f), Vec2(0.5f, 1.0f)};
83*35238bceSAndroid Build Coastguard Worker static const Vec3 s_constInVec3[2]   = {Vec3(1.1f, 0.1f, 0.5f), Vec3(-0.2f, 0.5f, 0.8f)};
84*35238bceSAndroid Build Coastguard Worker static const Vec4 s_constInVec4[2]   = {Vec4(1.4f, 0.2f, -0.5f, 0.7f), Vec4(0.2f, -1.0f, 0.5f, 0.8f)};
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker static const float s_constInMat2x2[2][4] = {
87*35238bceSAndroid Build Coastguard Worker     {
88*35238bceSAndroid Build Coastguard Worker         -0.1f,
89*35238bceSAndroid Build Coastguard Worker         1.0f,
90*35238bceSAndroid Build Coastguard Worker         -0.2f,
91*35238bceSAndroid Build Coastguard Worker         0.0f,
92*35238bceSAndroid Build Coastguard Worker     },
93*35238bceSAndroid Build Coastguard Worker     {
94*35238bceSAndroid Build Coastguard Worker         0.8f,
95*35238bceSAndroid Build Coastguard Worker         0.1f,
96*35238bceSAndroid Build Coastguard Worker         0.5f,
97*35238bceSAndroid Build Coastguard Worker         -0.9f,
98*35238bceSAndroid Build Coastguard Worker     },
99*35238bceSAndroid Build Coastguard Worker };
100*35238bceSAndroid Build Coastguard Worker static const float s_constInMat3x2[2][6] = {
101*35238bceSAndroid Build Coastguard Worker     {
102*35238bceSAndroid Build Coastguard Worker         0.8f,
103*35238bceSAndroid Build Coastguard Worker         -0.3f,
104*35238bceSAndroid Build Coastguard Worker         0.3f,
105*35238bceSAndroid Build Coastguard Worker         1.0f,
106*35238bceSAndroid Build Coastguard Worker         1.2f,
107*35238bceSAndroid Build Coastguard Worker         -1.2f,
108*35238bceSAndroid Build Coastguard Worker     },
109*35238bceSAndroid Build Coastguard Worker     {
110*35238bceSAndroid Build Coastguard Worker         1.2f,
111*35238bceSAndroid Build Coastguard Worker         -1.0f,
112*35238bceSAndroid Build Coastguard Worker         0.5f,
113*35238bceSAndroid Build Coastguard Worker         -0.8f,
114*35238bceSAndroid Build Coastguard Worker         1.1f,
115*35238bceSAndroid Build Coastguard Worker         0.3f,
116*35238bceSAndroid Build Coastguard Worker     },
117*35238bceSAndroid Build Coastguard Worker };
118*35238bceSAndroid Build Coastguard Worker static const float s_constInMat4x2[2][8] = {
119*35238bceSAndroid Build Coastguard Worker     {
120*35238bceSAndroid Build Coastguard Worker         -0.2f,
121*35238bceSAndroid Build Coastguard Worker         0.5f,
122*35238bceSAndroid Build Coastguard Worker         0.0f,
123*35238bceSAndroid Build Coastguard Worker         -1.0f,
124*35238bceSAndroid Build Coastguard Worker         1.2f,
125*35238bceSAndroid Build Coastguard Worker         -0.5f,
126*35238bceSAndroid Build Coastguard Worker         0.3f,
127*35238bceSAndroid Build Coastguard Worker         -0.9f,
128*35238bceSAndroid Build Coastguard Worker     },
129*35238bceSAndroid Build Coastguard Worker     {
130*35238bceSAndroid Build Coastguard Worker         1.0f,
131*35238bceSAndroid Build Coastguard Worker         0.1f,
132*35238bceSAndroid Build Coastguard Worker         -1.1f,
133*35238bceSAndroid Build Coastguard Worker         0.6f,
134*35238bceSAndroid Build Coastguard Worker         0.8f,
135*35238bceSAndroid Build Coastguard Worker         -1.2f,
136*35238bceSAndroid Build Coastguard Worker         -1.1f,
137*35238bceSAndroid Build Coastguard Worker         0.7f,
138*35238bceSAndroid Build Coastguard Worker     },
139*35238bceSAndroid Build Coastguard Worker };
140*35238bceSAndroid Build Coastguard Worker static const float s_constInMat2x3[2][6] = {
141*35238bceSAndroid Build Coastguard Worker     {
142*35238bceSAndroid Build Coastguard Worker         -0.6f,
143*35238bceSAndroid Build Coastguard Worker         -0.1f,
144*35238bceSAndroid Build Coastguard Worker         -0.7f,
145*35238bceSAndroid Build Coastguard Worker         -1.2f,
146*35238bceSAndroid Build Coastguard Worker         -0.2f,
147*35238bceSAndroid Build Coastguard Worker         0.0f,
148*35238bceSAndroid Build Coastguard Worker     },
149*35238bceSAndroid Build Coastguard Worker     {
150*35238bceSAndroid Build Coastguard Worker         1.1f,
151*35238bceSAndroid Build Coastguard Worker         0.6f,
152*35238bceSAndroid Build Coastguard Worker         0.8f,
153*35238bceSAndroid Build Coastguard Worker         1.0f,
154*35238bceSAndroid Build Coastguard Worker         0.7f,
155*35238bceSAndroid Build Coastguard Worker         0.1f,
156*35238bceSAndroid Build Coastguard Worker     },
157*35238bceSAndroid Build Coastguard Worker };
158*35238bceSAndroid Build Coastguard Worker static const float s_constInMat3x3[2][9] = {
159*35238bceSAndroid Build Coastguard Worker     {
160*35238bceSAndroid Build Coastguard Worker         -0.2f,
161*35238bceSAndroid Build Coastguard Worker         1.1f,
162*35238bceSAndroid Build Coastguard Worker         1.2f,
163*35238bceSAndroid Build Coastguard Worker         -1.0f,
164*35238bceSAndroid Build Coastguard Worker         1.2f,
165*35238bceSAndroid Build Coastguard Worker         0.5f,
166*35238bceSAndroid Build Coastguard Worker         0.7f,
167*35238bceSAndroid Build Coastguard Worker         -0.2f,
168*35238bceSAndroid Build Coastguard Worker         1.0f,
169*35238bceSAndroid Build Coastguard Worker     },
170*35238bceSAndroid Build Coastguard Worker     {
171*35238bceSAndroid Build Coastguard Worker         -0.1f,
172*35238bceSAndroid Build Coastguard Worker         -0.1f,
173*35238bceSAndroid Build Coastguard Worker         0.1f,
174*35238bceSAndroid Build Coastguard Worker         -0.1f,
175*35238bceSAndroid Build Coastguard Worker         -0.2f,
176*35238bceSAndroid Build Coastguard Worker         1.0f,
177*35238bceSAndroid Build Coastguard Worker         -0.5f,
178*35238bceSAndroid Build Coastguard Worker         0.1f,
179*35238bceSAndroid Build Coastguard Worker         -0.4f,
180*35238bceSAndroid Build Coastguard Worker     },
181*35238bceSAndroid Build Coastguard Worker };
182*35238bceSAndroid Build Coastguard Worker static const float s_constInMat4x3[2][12] = {
183*35238bceSAndroid Build Coastguard Worker     {
184*35238bceSAndroid Build Coastguard Worker         -0.9f,
185*35238bceSAndroid Build Coastguard Worker         0.0f,
186*35238bceSAndroid Build Coastguard Worker         0.6f,
187*35238bceSAndroid Build Coastguard Worker         0.2f,
188*35238bceSAndroid Build Coastguard Worker         0.9f,
189*35238bceSAndroid Build Coastguard Worker         -0.1f,
190*35238bceSAndroid Build Coastguard Worker         -0.3f,
191*35238bceSAndroid Build Coastguard Worker         -0.7f,
192*35238bceSAndroid Build Coastguard Worker         -0.1f,
193*35238bceSAndroid Build Coastguard Worker         0.1f,
194*35238bceSAndroid Build Coastguard Worker         1.0f,
195*35238bceSAndroid Build Coastguard Worker         0.0f,
196*35238bceSAndroid Build Coastguard Worker     },
197*35238bceSAndroid Build Coastguard Worker     {
198*35238bceSAndroid Build Coastguard Worker         0.5f,
199*35238bceSAndroid Build Coastguard Worker         0.7f,
200*35238bceSAndroid Build Coastguard Worker         0.7f,
201*35238bceSAndroid Build Coastguard Worker         1.2f,
202*35238bceSAndroid Build Coastguard Worker         1.1f,
203*35238bceSAndroid Build Coastguard Worker         0.1f,
204*35238bceSAndroid Build Coastguard Worker         1.0f,
205*35238bceSAndroid Build Coastguard Worker         -1.0f,
206*35238bceSAndroid Build Coastguard Worker         -0.2f,
207*35238bceSAndroid Build Coastguard Worker         -0.2f,
208*35238bceSAndroid Build Coastguard Worker         -0.3f,
209*35238bceSAndroid Build Coastguard Worker         -0.5f,
210*35238bceSAndroid Build Coastguard Worker     },
211*35238bceSAndroid Build Coastguard Worker };
212*35238bceSAndroid Build Coastguard Worker static const float s_constInMat2x4[2][8] = {
213*35238bceSAndroid Build Coastguard Worker     {
214*35238bceSAndroid Build Coastguard Worker         -0.6f,
215*35238bceSAndroid Build Coastguard Worker         -1.1f,
216*35238bceSAndroid Build Coastguard Worker         -0.6f,
217*35238bceSAndroid Build Coastguard Worker         -0.6f,
218*35238bceSAndroid Build Coastguard Worker         -0.2f,
219*35238bceSAndroid Build Coastguard Worker         -0.6f,
220*35238bceSAndroid Build Coastguard Worker         -0.1f,
221*35238bceSAndroid Build Coastguard Worker         -0.1f,
222*35238bceSAndroid Build Coastguard Worker     },
223*35238bceSAndroid Build Coastguard Worker     {
224*35238bceSAndroid Build Coastguard Worker         -1.2f,
225*35238bceSAndroid Build Coastguard Worker         -1.0f,
226*35238bceSAndroid Build Coastguard Worker         0.7f,
227*35238bceSAndroid Build Coastguard Worker         -1.0f,
228*35238bceSAndroid Build Coastguard Worker         0.7f,
229*35238bceSAndroid Build Coastguard Worker         0.7f,
230*35238bceSAndroid Build Coastguard Worker         -0.4f,
231*35238bceSAndroid Build Coastguard Worker         -0.3f,
232*35238bceSAndroid Build Coastguard Worker     },
233*35238bceSAndroid Build Coastguard Worker };
234*35238bceSAndroid Build Coastguard Worker static const float s_constInMat3x4[2][12] = {
235*35238bceSAndroid Build Coastguard Worker     {
236*35238bceSAndroid Build Coastguard Worker         0.6f,
237*35238bceSAndroid Build Coastguard Worker         -0.4f,
238*35238bceSAndroid Build Coastguard Worker         1.2f,
239*35238bceSAndroid Build Coastguard Worker         0.9f,
240*35238bceSAndroid Build Coastguard Worker         0.8f,
241*35238bceSAndroid Build Coastguard Worker         0.4f,
242*35238bceSAndroid Build Coastguard Worker         1.1f,
243*35238bceSAndroid Build Coastguard Worker         0.3f,
244*35238bceSAndroid Build Coastguard Worker         0.5f,
245*35238bceSAndroid Build Coastguard Worker         -0.2f,
246*35238bceSAndroid Build Coastguard Worker         0.0f,
247*35238bceSAndroid Build Coastguard Worker         1.1f,
248*35238bceSAndroid Build Coastguard Worker     },
249*35238bceSAndroid Build Coastguard Worker     {
250*35238bceSAndroid Build Coastguard Worker         -0.8f,
251*35238bceSAndroid Build Coastguard Worker         1.2f,
252*35238bceSAndroid Build Coastguard Worker         -0.2f,
253*35238bceSAndroid Build Coastguard Worker         -1.1f,
254*35238bceSAndroid Build Coastguard Worker         -0.9f,
255*35238bceSAndroid Build Coastguard Worker         -0.5f,
256*35238bceSAndroid Build Coastguard Worker         -1.2f,
257*35238bceSAndroid Build Coastguard Worker         1.0f,
258*35238bceSAndroid Build Coastguard Worker         1.2f,
259*35238bceSAndroid Build Coastguard Worker         0.1f,
260*35238bceSAndroid Build Coastguard Worker         -0.7f,
261*35238bceSAndroid Build Coastguard Worker         -0.5f,
262*35238bceSAndroid Build Coastguard Worker     },
263*35238bceSAndroid Build Coastguard Worker };
264*35238bceSAndroid Build Coastguard Worker static const float s_constInMat4x4[2][16] = {
265*35238bceSAndroid Build Coastguard Worker     {
266*35238bceSAndroid Build Coastguard Worker         0.3f,
267*35238bceSAndroid Build Coastguard Worker         0.9f,
268*35238bceSAndroid Build Coastguard Worker         -0.2f,
269*35238bceSAndroid Build Coastguard Worker         1.0f,
270*35238bceSAndroid Build Coastguard Worker         -0.4f,
271*35238bceSAndroid Build Coastguard Worker         -0.6f,
272*35238bceSAndroid Build Coastguard Worker         0.6f,
273*35238bceSAndroid Build Coastguard Worker         -1.0f,
274*35238bceSAndroid Build Coastguard Worker         -0.9f,
275*35238bceSAndroid Build Coastguard Worker         -0.1f,
276*35238bceSAndroid Build Coastguard Worker         0.3f,
277*35238bceSAndroid Build Coastguard Worker         -0.2f,
278*35238bceSAndroid Build Coastguard Worker         -0.3f,
279*35238bceSAndroid Build Coastguard Worker         -0.9f,
280*35238bceSAndroid Build Coastguard Worker         1.0f,
281*35238bceSAndroid Build Coastguard Worker         0.1f,
282*35238bceSAndroid Build Coastguard Worker     },
283*35238bceSAndroid Build Coastguard Worker     {
284*35238bceSAndroid Build Coastguard Worker         0.4f,
285*35238bceSAndroid Build Coastguard Worker         -0.7f,
286*35238bceSAndroid Build Coastguard Worker         -0.8f,
287*35238bceSAndroid Build Coastguard Worker         0.7f,
288*35238bceSAndroid Build Coastguard Worker         -0.4f,
289*35238bceSAndroid Build Coastguard Worker         -0.8f,
290*35238bceSAndroid Build Coastguard Worker         0.6f,
291*35238bceSAndroid Build Coastguard Worker         -0.3f,
292*35238bceSAndroid Build Coastguard Worker         0.7f,
293*35238bceSAndroid Build Coastguard Worker         -1.0f,
294*35238bceSAndroid Build Coastguard Worker         0.1f,
295*35238bceSAndroid Build Coastguard Worker         -0.3f,
296*35238bceSAndroid Build Coastguard Worker         0.2f,
297*35238bceSAndroid Build Coastguard Worker         0.6f,
298*35238bceSAndroid Build Coastguard Worker         0.4f,
299*35238bceSAndroid Build Coastguard Worker         -1.0f,
300*35238bceSAndroid Build Coastguard Worker     },
301*35238bceSAndroid Build Coastguard Worker };
302*35238bceSAndroid Build Coastguard Worker 
303*35238bceSAndroid Build Coastguard Worker namespace MatrixCaseUtils
304*35238bceSAndroid Build Coastguard Worker {
305*35238bceSAndroid Build Coastguard Worker 
306*35238bceSAndroid Build Coastguard Worker enum InputType
307*35238bceSAndroid Build Coastguard Worker {
308*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_CONST = 0,
309*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_UNIFORM,
310*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_DYNAMIC,
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_LAST
313*35238bceSAndroid Build Coastguard Worker };
314*35238bceSAndroid Build Coastguard Worker 
315*35238bceSAndroid Build Coastguard Worker struct ShaderInput
316*35238bceSAndroid Build Coastguard Worker {
ShaderInputdeqp::gles3::Functional::MatrixCaseUtils::ShaderInput317*35238bceSAndroid Build Coastguard Worker     ShaderInput(InputType inputType_, DataType dataType_, Precision precision_)
318*35238bceSAndroid Build Coastguard Worker         : inputType(inputType_)
319*35238bceSAndroid Build Coastguard Worker         , dataType(dataType_)
320*35238bceSAndroid Build Coastguard Worker         , precision(precision_)
321*35238bceSAndroid Build Coastguard Worker     {
322*35238bceSAndroid Build Coastguard Worker     }
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker     InputType inputType;
325*35238bceSAndroid Build Coastguard Worker     DataType dataType;
326*35238bceSAndroid Build Coastguard Worker     Precision precision;
327*35238bceSAndroid Build Coastguard Worker };
328*35238bceSAndroid Build Coastguard Worker 
329*35238bceSAndroid Build Coastguard Worker enum MatrixOp
330*35238bceSAndroid Build Coastguard Worker {
331*35238bceSAndroid Build Coastguard Worker     OP_ADD = 0,
332*35238bceSAndroid Build Coastguard Worker     OP_SUB,
333*35238bceSAndroid Build Coastguard Worker     OP_MUL,
334*35238bceSAndroid Build Coastguard Worker     OP_DIV,
335*35238bceSAndroid Build Coastguard Worker     OP_COMP_MUL,
336*35238bceSAndroid Build Coastguard Worker     OP_OUTER_PRODUCT,
337*35238bceSAndroid Build Coastguard Worker     OP_TRANSPOSE,
338*35238bceSAndroid Build Coastguard Worker     OP_INVERSE,
339*35238bceSAndroid Build Coastguard Worker     OP_DETERMINANT,
340*35238bceSAndroid Build Coastguard Worker     OP_UNARY_PLUS,
341*35238bceSAndroid Build Coastguard Worker     OP_NEGATION,
342*35238bceSAndroid Build Coastguard Worker     OP_PRE_INCREMENT,
343*35238bceSAndroid Build Coastguard Worker     OP_PRE_DECREMENT,
344*35238bceSAndroid Build Coastguard Worker     OP_POST_INCREMENT,
345*35238bceSAndroid Build Coastguard Worker     OP_POST_DECREMENT,
346*35238bceSAndroid Build Coastguard Worker     OP_ADD_INTO,
347*35238bceSAndroid Build Coastguard Worker     OP_SUBTRACT_FROM,
348*35238bceSAndroid Build Coastguard Worker     OP_MULTIPLY_INTO,
349*35238bceSAndroid Build Coastguard Worker     OP_DIVIDE_INTO,
350*35238bceSAndroid Build Coastguard Worker     OP_LAST
351*35238bceSAndroid Build Coastguard Worker };
352*35238bceSAndroid Build Coastguard Worker 
353*35238bceSAndroid Build Coastguard Worker // Type traits.
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker template <int DataT>
356*35238bceSAndroid Build Coastguard Worker struct TypeTraits;
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker #define DECLARE_TYPE_TRAIT(DATATYPE, TYPE) \
359*35238bceSAndroid Build Coastguard Worker     template <>                            \
360*35238bceSAndroid Build Coastguard Worker     struct TypeTraits<DATATYPE>            \
361*35238bceSAndroid Build Coastguard Worker     {                                      \
362*35238bceSAndroid Build Coastguard Worker         typedef TYPE Type;                 \
363*35238bceSAndroid Build Coastguard Worker     }
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT, float);
366*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC2, tcu::Vec2);
367*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC3, tcu::Vec3);
368*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC4, tcu::Vec4);
369*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2, tcu::Mat2);
370*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X3, tcu::Mat2x3);
371*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X4, tcu::Mat2x4);
372*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X2, tcu::Mat3x2);
373*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3, tcu::Mat3);
374*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X4, tcu::Mat3x4);
375*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X2, tcu::Mat4x2);
376*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X3, tcu::Mat4x3);
377*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4, tcu::Mat4);
378*35238bceSAndroid Build Coastguard Worker 
379*35238bceSAndroid Build Coastguard Worker // Operation info
380*35238bceSAndroid Build Coastguard Worker 
381*35238bceSAndroid Build Coastguard Worker enum OperationType
382*35238bceSAndroid Build Coastguard Worker {
383*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_BINARY_OPERATOR = 0,
384*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_BINARY_FUNCTION,
385*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_UNARY_PREFIX_OPERATOR,
386*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_UNARY_POSTFIX_OPERATOR,
387*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_UNARY_FUNCTION,
388*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_ASSIGNMENT,
389*35238bceSAndroid Build Coastguard Worker 
390*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_LAST
391*35238bceSAndroid Build Coastguard Worker };
392*35238bceSAndroid Build Coastguard Worker 
getOperationName(MatrixOp op)393*35238bceSAndroid Build Coastguard Worker static const char *getOperationName(MatrixOp op)
394*35238bceSAndroid Build Coastguard Worker {
395*35238bceSAndroid Build Coastguard Worker     switch (op)
396*35238bceSAndroid Build Coastguard Worker     {
397*35238bceSAndroid Build Coastguard Worker     case OP_ADD:
398*35238bceSAndroid Build Coastguard Worker         return "+";
399*35238bceSAndroid Build Coastguard Worker     case OP_SUB:
400*35238bceSAndroid Build Coastguard Worker         return "-";
401*35238bceSAndroid Build Coastguard Worker     case OP_MUL:
402*35238bceSAndroid Build Coastguard Worker         return "*";
403*35238bceSAndroid Build Coastguard Worker     case OP_DIV:
404*35238bceSAndroid Build Coastguard Worker         return "/";
405*35238bceSAndroid Build Coastguard Worker     case OP_COMP_MUL:
406*35238bceSAndroid Build Coastguard Worker         return "matrixCompMult";
407*35238bceSAndroid Build Coastguard Worker     case OP_OUTER_PRODUCT:
408*35238bceSAndroid Build Coastguard Worker         return "outerProduct";
409*35238bceSAndroid Build Coastguard Worker     case OP_TRANSPOSE:
410*35238bceSAndroid Build Coastguard Worker         return "transpose";
411*35238bceSAndroid Build Coastguard Worker     case OP_INVERSE:
412*35238bceSAndroid Build Coastguard Worker         return "inverse";
413*35238bceSAndroid Build Coastguard Worker     case OP_DETERMINANT:
414*35238bceSAndroid Build Coastguard Worker         return "determinant";
415*35238bceSAndroid Build Coastguard Worker     case OP_UNARY_PLUS:
416*35238bceSAndroid Build Coastguard Worker         return "+";
417*35238bceSAndroid Build Coastguard Worker     case OP_NEGATION:
418*35238bceSAndroid Build Coastguard Worker         return "-";
419*35238bceSAndroid Build Coastguard Worker     case OP_PRE_INCREMENT:
420*35238bceSAndroid Build Coastguard Worker         return "++";
421*35238bceSAndroid Build Coastguard Worker     case OP_PRE_DECREMENT:
422*35238bceSAndroid Build Coastguard Worker         return "--";
423*35238bceSAndroid Build Coastguard Worker     case OP_POST_INCREMENT:
424*35238bceSAndroid Build Coastguard Worker         return "++";
425*35238bceSAndroid Build Coastguard Worker     case OP_POST_DECREMENT:
426*35238bceSAndroid Build Coastguard Worker         return "--";
427*35238bceSAndroid Build Coastguard Worker     case OP_ADD_INTO:
428*35238bceSAndroid Build Coastguard Worker         return "+=";
429*35238bceSAndroid Build Coastguard Worker     case OP_SUBTRACT_FROM:
430*35238bceSAndroid Build Coastguard Worker         return "-=";
431*35238bceSAndroid Build Coastguard Worker     case OP_MULTIPLY_INTO:
432*35238bceSAndroid Build Coastguard Worker         return "*=";
433*35238bceSAndroid Build Coastguard Worker     case OP_DIVIDE_INTO:
434*35238bceSAndroid Build Coastguard Worker         return "/=";
435*35238bceSAndroid Build Coastguard Worker 
436*35238bceSAndroid Build Coastguard Worker     default:
437*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
438*35238bceSAndroid Build Coastguard Worker         return "";
439*35238bceSAndroid Build Coastguard Worker     }
440*35238bceSAndroid Build Coastguard Worker }
441*35238bceSAndroid Build Coastguard Worker 
getOperationType(MatrixOp op)442*35238bceSAndroid Build Coastguard Worker static OperationType getOperationType(MatrixOp op)
443*35238bceSAndroid Build Coastguard Worker {
444*35238bceSAndroid Build Coastguard Worker     switch (op)
445*35238bceSAndroid Build Coastguard Worker     {
446*35238bceSAndroid Build Coastguard Worker     case OP_ADD:
447*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
448*35238bceSAndroid Build Coastguard Worker     case OP_SUB:
449*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
450*35238bceSAndroid Build Coastguard Worker     case OP_MUL:
451*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
452*35238bceSAndroid Build Coastguard Worker     case OP_DIV:
453*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
454*35238bceSAndroid Build Coastguard Worker     case OP_COMP_MUL:
455*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_FUNCTION;
456*35238bceSAndroid Build Coastguard Worker     case OP_OUTER_PRODUCT:
457*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_FUNCTION;
458*35238bceSAndroid Build Coastguard Worker     case OP_TRANSPOSE:
459*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_FUNCTION;
460*35238bceSAndroid Build Coastguard Worker     case OP_INVERSE:
461*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_FUNCTION;
462*35238bceSAndroid Build Coastguard Worker     case OP_DETERMINANT:
463*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_FUNCTION;
464*35238bceSAndroid Build Coastguard Worker     case OP_UNARY_PLUS:
465*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
466*35238bceSAndroid Build Coastguard Worker     case OP_NEGATION:
467*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
468*35238bceSAndroid Build Coastguard Worker     case OP_PRE_INCREMENT:
469*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
470*35238bceSAndroid Build Coastguard Worker     case OP_PRE_DECREMENT:
471*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
472*35238bceSAndroid Build Coastguard Worker     case OP_POST_INCREMENT:
473*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
474*35238bceSAndroid Build Coastguard Worker     case OP_POST_DECREMENT:
475*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
476*35238bceSAndroid Build Coastguard Worker     case OP_ADD_INTO:
477*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
478*35238bceSAndroid Build Coastguard Worker     case OP_SUBTRACT_FROM:
479*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
480*35238bceSAndroid Build Coastguard Worker     case OP_MULTIPLY_INTO:
481*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
482*35238bceSAndroid Build Coastguard Worker     case OP_DIVIDE_INTO:
483*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
484*35238bceSAndroid Build Coastguard Worker     default:
485*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
486*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_LAST;
487*35238bceSAndroid Build Coastguard Worker     }
488*35238bceSAndroid Build Coastguard Worker }
489*35238bceSAndroid Build Coastguard Worker 
490*35238bceSAndroid Build Coastguard Worker enum TestMatrixType
491*35238bceSAndroid Build Coastguard Worker {
492*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_DEFAULT = 0,
493*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_NEGATED,
494*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_INCREMENTED,
495*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_DECREMENTED,
496*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_NEGATED_INCREMENTED,
497*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_INCREMENTED_LESS,
498*35238bceSAndroid Build Coastguard Worker 
499*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_LAST
500*35238bceSAndroid Build Coastguard Worker };
501*35238bceSAndroid Build Coastguard Worker 
getOperationTestMatrixType(MatrixOp op)502*35238bceSAndroid Build Coastguard Worker static TestMatrixType getOperationTestMatrixType(MatrixOp op)
503*35238bceSAndroid Build Coastguard Worker {
504*35238bceSAndroid Build Coastguard Worker     switch (op)
505*35238bceSAndroid Build Coastguard Worker     {
506*35238bceSAndroid Build Coastguard Worker     case OP_ADD:
507*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
508*35238bceSAndroid Build Coastguard Worker     case OP_SUB:
509*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
510*35238bceSAndroid Build Coastguard Worker     case OP_MUL:
511*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
512*35238bceSAndroid Build Coastguard Worker     case OP_DIV:
513*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
514*35238bceSAndroid Build Coastguard Worker     case OP_COMP_MUL:
515*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
516*35238bceSAndroid Build Coastguard Worker     case OP_OUTER_PRODUCT:
517*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
518*35238bceSAndroid Build Coastguard Worker     case OP_TRANSPOSE:
519*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
520*35238bceSAndroid Build Coastguard Worker     case OP_INVERSE:
521*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
522*35238bceSAndroid Build Coastguard Worker     case OP_DETERMINANT:
523*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
524*35238bceSAndroid Build Coastguard Worker     case OP_UNARY_PLUS:
525*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DECREMENTED;
526*35238bceSAndroid Build Coastguard Worker     case OP_NEGATION:
527*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_NEGATED_INCREMENTED;
528*35238bceSAndroid Build Coastguard Worker     case OP_PRE_INCREMENT:
529*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_NEGATED;
530*35238bceSAndroid Build Coastguard Worker     case OP_PRE_DECREMENT:
531*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_INCREMENTED;
532*35238bceSAndroid Build Coastguard Worker     case OP_POST_INCREMENT:
533*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_NEGATED;
534*35238bceSAndroid Build Coastguard Worker     case OP_POST_DECREMENT:
535*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
536*35238bceSAndroid Build Coastguard Worker     case OP_ADD_INTO:
537*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
538*35238bceSAndroid Build Coastguard Worker     case OP_SUBTRACT_FROM:
539*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_INCREMENTED_LESS;
540*35238bceSAndroid Build Coastguard Worker     case OP_MULTIPLY_INTO:
541*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_NEGATED;
542*35238bceSAndroid Build Coastguard Worker     case OP_DIVIDE_INTO:
543*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DECREMENTED;
544*35238bceSAndroid Build Coastguard Worker 
545*35238bceSAndroid Build Coastguard Worker     default:
546*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
547*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_LAST;
548*35238bceSAndroid Build Coastguard Worker     }
549*35238bceSAndroid Build Coastguard Worker }
550*35238bceSAndroid Build Coastguard Worker 
isOperationBinary(MatrixOp op)551*35238bceSAndroid Build Coastguard Worker static bool isOperationBinary(MatrixOp op)
552*35238bceSAndroid Build Coastguard Worker {
553*35238bceSAndroid Build Coastguard Worker     return getOperationType(op) == OPERATIONTYPE_BINARY_OPERATOR ||
554*35238bceSAndroid Build Coastguard Worker            getOperationType(op) == OPERATIONTYPE_BINARY_FUNCTION || getOperationType(op) == OPERATIONTYPE_ASSIGNMENT;
555*35238bceSAndroid Build Coastguard Worker }
556*35238bceSAndroid Build Coastguard Worker 
isOperationMatrixScalar(MatrixOp op)557*35238bceSAndroid Build Coastguard Worker static bool isOperationMatrixScalar(MatrixOp op)
558*35238bceSAndroid Build Coastguard Worker {
559*35238bceSAndroid Build Coastguard Worker     return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV;
560*35238bceSAndroid Build Coastguard Worker }
561*35238bceSAndroid Build Coastguard Worker 
isOperationMatrixVector(MatrixOp op)562*35238bceSAndroid Build Coastguard Worker static bool isOperationMatrixVector(MatrixOp op)
563*35238bceSAndroid Build Coastguard Worker {
564*35238bceSAndroid Build Coastguard Worker     return op == OP_MUL;
565*35238bceSAndroid Build Coastguard Worker }
566*35238bceSAndroid Build Coastguard Worker 
isOperationArithmeticMatrixMatrix(MatrixOp op)567*35238bceSAndroid Build Coastguard Worker static bool isOperationArithmeticMatrixMatrix(MatrixOp op)
568*35238bceSAndroid Build Coastguard Worker {
569*35238bceSAndroid Build Coastguard Worker     return op == OP_MUL;
570*35238bceSAndroid Build Coastguard Worker }
571*35238bceSAndroid Build Coastguard Worker 
isOperationComponentwiseMatrixMatrix(MatrixOp op)572*35238bceSAndroid Build Coastguard Worker static bool isOperationComponentwiseMatrixMatrix(MatrixOp op)
573*35238bceSAndroid Build Coastguard Worker {
574*35238bceSAndroid Build Coastguard Worker     return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV || op == OP_COMP_MUL;
575*35238bceSAndroid Build Coastguard Worker }
576*35238bceSAndroid Build Coastguard Worker 
isOperationVectorVector(MatrixOp op)577*35238bceSAndroid Build Coastguard Worker static bool isOperationVectorVector(MatrixOp op)
578*35238bceSAndroid Build Coastguard Worker {
579*35238bceSAndroid Build Coastguard Worker     return op == OP_OUTER_PRODUCT;
580*35238bceSAndroid Build Coastguard Worker }
581*35238bceSAndroid Build Coastguard Worker 
isOperationUnaryAnyMatrix(MatrixOp op)582*35238bceSAndroid Build Coastguard Worker static bool isOperationUnaryAnyMatrix(MatrixOp op)
583*35238bceSAndroid Build Coastguard Worker {
584*35238bceSAndroid Build Coastguard Worker     return op == OP_TRANSPOSE || op == OP_UNARY_PLUS || op == OP_NEGATION || op == OP_PRE_INCREMENT ||
585*35238bceSAndroid Build Coastguard Worker            op == OP_PRE_DECREMENT || op == OP_POST_INCREMENT || op == OP_POST_DECREMENT;
586*35238bceSAndroid Build Coastguard Worker }
587*35238bceSAndroid Build Coastguard Worker 
isOperationUnarySymmetricMatrix(MatrixOp op)588*35238bceSAndroid Build Coastguard Worker static bool isOperationUnarySymmetricMatrix(MatrixOp op)
589*35238bceSAndroid Build Coastguard Worker {
590*35238bceSAndroid Build Coastguard Worker     return op == OP_INVERSE || op == OP_DETERMINANT;
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker 
isOperationValueModifying(MatrixOp op)593*35238bceSAndroid Build Coastguard Worker static bool isOperationValueModifying(MatrixOp op)
594*35238bceSAndroid Build Coastguard Worker {
595*35238bceSAndroid Build Coastguard Worker     return op == OP_PRE_INCREMENT || op == OP_PRE_DECREMENT || op == OP_POST_INCREMENT || op == OP_POST_DECREMENT;
596*35238bceSAndroid Build Coastguard Worker }
597*35238bceSAndroid Build Coastguard Worker 
isOperationAssignment(MatrixOp op)598*35238bceSAndroid Build Coastguard Worker static bool isOperationAssignment(MatrixOp op)
599*35238bceSAndroid Build Coastguard Worker {
600*35238bceSAndroid Build Coastguard Worker     return op == OP_ADD_INTO || op == OP_SUBTRACT_FROM || op == OP_MULTIPLY_INTO || op == OP_DIVIDE_INTO;
601*35238bceSAndroid Build Coastguard Worker }
602*35238bceSAndroid Build Coastguard Worker 
isOperationAssignmentAnyMatrix(MatrixOp op)603*35238bceSAndroid Build Coastguard Worker static bool isOperationAssignmentAnyMatrix(MatrixOp op)
604*35238bceSAndroid Build Coastguard Worker {
605*35238bceSAndroid Build Coastguard Worker     return op == OP_ADD_INTO || op == OP_SUBTRACT_FROM || op == OP_DIVIDE_INTO;
606*35238bceSAndroid Build Coastguard Worker }
607*35238bceSAndroid Build Coastguard Worker 
isOperationAssignmentSymmetricMatrix(MatrixOp op)608*35238bceSAndroid Build Coastguard Worker static bool isOperationAssignmentSymmetricMatrix(MatrixOp op)
609*35238bceSAndroid Build Coastguard Worker {
610*35238bceSAndroid Build Coastguard Worker     return op == OP_MULTIPLY_INTO;
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker 
613*35238bceSAndroid Build Coastguard Worker // Operation nature
614*35238bceSAndroid Build Coastguard Worker 
615*35238bceSAndroid Build Coastguard Worker enum OperationNature
616*35238bceSAndroid Build Coastguard Worker {
617*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_PURE = 0,
618*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_MUTATING,
619*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_ASSIGNMENT,
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_LAST
622*35238bceSAndroid Build Coastguard Worker };
623*35238bceSAndroid Build Coastguard Worker 
getOperationNature(MatrixOp op)624*35238bceSAndroid Build Coastguard Worker static OperationNature getOperationNature(MatrixOp op)
625*35238bceSAndroid Build Coastguard Worker {
626*35238bceSAndroid Build Coastguard Worker     if (isOperationAssignment(op))
627*35238bceSAndroid Build Coastguard Worker         return OPERATIONNATURE_ASSIGNMENT;
628*35238bceSAndroid Build Coastguard Worker 
629*35238bceSAndroid Build Coastguard Worker     if (isOperationValueModifying(op))
630*35238bceSAndroid Build Coastguard Worker         return OPERATIONNATURE_MUTATING;
631*35238bceSAndroid Build Coastguard Worker 
632*35238bceSAndroid Build Coastguard Worker     return OPERATIONNATURE_PURE;
633*35238bceSAndroid Build Coastguard Worker }
634*35238bceSAndroid Build Coastguard Worker 
635*35238bceSAndroid Build Coastguard Worker // Input value loader.
636*35238bceSAndroid Build Coastguard Worker 
637*35238bceSAndroid Build Coastguard Worker template <int InputT, int DataT>
638*35238bceSAndroid Build Coastguard Worker typename TypeTraits<DataT>::Type getInputValue(const ShaderEvalContext &evalCtx, int inputNdx);
639*35238bceSAndroid Build Coastguard Worker 
640*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)641*35238bceSAndroid Build Coastguard Worker inline float getInputValue<INPUTTYPE_CONST, TYPE_FLOAT>(const ShaderEvalContext &evalCtx, int inputNdx)
642*35238bceSAndroid Build Coastguard Worker {
643*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
644*35238bceSAndroid Build Coastguard Worker     return s_constInFloat[inputNdx];
645*35238bceSAndroid Build Coastguard Worker }
646*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)647*35238bceSAndroid Build Coastguard Worker inline tcu::Vec2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC2>(const ShaderEvalContext &evalCtx, int inputNdx)
648*35238bceSAndroid Build Coastguard Worker {
649*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
650*35238bceSAndroid Build Coastguard Worker     return s_constInVec2[inputNdx];
651*35238bceSAndroid Build Coastguard Worker }
652*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)653*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC3>(const ShaderEvalContext &evalCtx, int inputNdx)
654*35238bceSAndroid Build Coastguard Worker {
655*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
656*35238bceSAndroid Build Coastguard Worker     return s_constInVec3[inputNdx];
657*35238bceSAndroid Build Coastguard Worker }
658*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)659*35238bceSAndroid Build Coastguard Worker inline tcu::Vec4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC4>(const ShaderEvalContext &evalCtx, int inputNdx)
660*35238bceSAndroid Build Coastguard Worker {
661*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
662*35238bceSAndroid Build Coastguard Worker     return s_constInVec4[inputNdx];
663*35238bceSAndroid Build Coastguard Worker }
664*35238bceSAndroid Build Coastguard Worker 
665*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)666*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT2>(const ShaderEvalContext &evalCtx, int inputNdx)
667*35238bceSAndroid Build Coastguard Worker {
668*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
669*35238bceSAndroid Build Coastguard Worker     return tcu::Mat2(s_constInMat2x2[inputNdx]);
670*35238bceSAndroid Build Coastguard Worker }
671*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)672*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2x3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT2X3>(const ShaderEvalContext &evalCtx, int inputNdx)
673*35238bceSAndroid Build Coastguard Worker {
674*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
675*35238bceSAndroid Build Coastguard Worker     return tcu::Mat2x3(s_constInMat2x3[inputNdx]);
676*35238bceSAndroid Build Coastguard Worker }
677*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)678*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2x4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT2X4>(const ShaderEvalContext &evalCtx, int inputNdx)
679*35238bceSAndroid Build Coastguard Worker {
680*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
681*35238bceSAndroid Build Coastguard Worker     return tcu::Mat2x4(s_constInMat2x4[inputNdx]);
682*35238bceSAndroid Build Coastguard Worker }
683*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)684*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3x2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT3X2>(const ShaderEvalContext &evalCtx, int inputNdx)
685*35238bceSAndroid Build Coastguard Worker {
686*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
687*35238bceSAndroid Build Coastguard Worker     return tcu::Mat3x2(s_constInMat3x2[inputNdx]);
688*35238bceSAndroid Build Coastguard Worker }
689*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)690*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT3>(const ShaderEvalContext &evalCtx, int inputNdx)
691*35238bceSAndroid Build Coastguard Worker {
692*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
693*35238bceSAndroid Build Coastguard Worker     return tcu::Mat3(s_constInMat3x3[inputNdx]);
694*35238bceSAndroid Build Coastguard Worker }
695*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)696*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3x4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT3X4>(const ShaderEvalContext &evalCtx, int inputNdx)
697*35238bceSAndroid Build Coastguard Worker {
698*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
699*35238bceSAndroid Build Coastguard Worker     return tcu::Mat3x4(s_constInMat3x4[inputNdx]);
700*35238bceSAndroid Build Coastguard Worker }
701*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)702*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4x2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT4X2>(const ShaderEvalContext &evalCtx, int inputNdx)
703*35238bceSAndroid Build Coastguard Worker {
704*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
705*35238bceSAndroid Build Coastguard Worker     return tcu::Mat4x2(s_constInMat4x2[inputNdx]);
706*35238bceSAndroid Build Coastguard Worker }
707*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)708*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4x3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT4X3>(const ShaderEvalContext &evalCtx, int inputNdx)
709*35238bceSAndroid Build Coastguard Worker {
710*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
711*35238bceSAndroid Build Coastguard Worker     return tcu::Mat4x3(s_constInMat4x3[inputNdx]);
712*35238bceSAndroid Build Coastguard Worker }
713*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)714*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT4>(const ShaderEvalContext &evalCtx, int inputNdx)
715*35238bceSAndroid Build Coastguard Worker {
716*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
717*35238bceSAndroid Build Coastguard Worker     return tcu::Mat4(s_constInMat4x4[inputNdx]);
718*35238bceSAndroid Build Coastguard Worker }
719*35238bceSAndroid Build Coastguard Worker 
720*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)721*35238bceSAndroid Build Coastguard Worker inline float getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT>(const ShaderEvalContext &evalCtx, int inputNdx)
722*35238bceSAndroid Build Coastguard Worker {
723*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
724*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.x();
725*35238bceSAndroid Build Coastguard Worker }
726*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)727*35238bceSAndroid Build Coastguard Worker inline tcu::Vec2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC2>(const ShaderEvalContext &evalCtx, int inputNdx)
728*35238bceSAndroid Build Coastguard Worker {
729*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
730*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.swizzle(0, 1);
731*35238bceSAndroid Build Coastguard Worker }
732*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)733*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC3>(const ShaderEvalContext &evalCtx, int inputNdx)
734*35238bceSAndroid Build Coastguard Worker {
735*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
736*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.swizzle(0, 1, 2);
737*35238bceSAndroid Build Coastguard Worker }
738*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)739*35238bceSAndroid Build Coastguard Worker inline tcu::Vec4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC4>(const ShaderEvalContext &evalCtx, int inputNdx)
740*35238bceSAndroid Build Coastguard Worker {
741*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
742*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.swizzle(0, 1, 2, 3);
743*35238bceSAndroid Build Coastguard Worker }
744*35238bceSAndroid Build Coastguard Worker 
745*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)746*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2>(const ShaderEvalContext &evalCtx, int inputNdx)
747*35238bceSAndroid Build Coastguard Worker {
748*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
749*35238bceSAndroid Build Coastguard Worker     tcu::Mat2 m;
750*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1));
751*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1));
752*35238bceSAndroid Build Coastguard Worker     return m;
753*35238bceSAndroid Build Coastguard Worker }
754*35238bceSAndroid Build Coastguard Worker 
755*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)756*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X3>(const ShaderEvalContext &evalCtx, int inputNdx)
757*35238bceSAndroid Build Coastguard Worker {
758*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
759*35238bceSAndroid Build Coastguard Worker     tcu::Mat2x3 m;
760*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1, 2));
761*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1, 2));
762*35238bceSAndroid Build Coastguard Worker     return m;
763*35238bceSAndroid Build Coastguard Worker }
764*35238bceSAndroid Build Coastguard Worker 
765*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)766*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X4>(const ShaderEvalContext &evalCtx, int inputNdx)
767*35238bceSAndroid Build Coastguard Worker {
768*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
769*35238bceSAndroid Build Coastguard Worker     tcu::Mat2x4 m;
770*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0]);
771*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1]);
772*35238bceSAndroid Build Coastguard Worker     return m;
773*35238bceSAndroid Build Coastguard Worker }
774*35238bceSAndroid Build Coastguard Worker 
775*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)776*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X2>(const ShaderEvalContext &evalCtx, int inputNdx)
777*35238bceSAndroid Build Coastguard Worker {
778*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
779*35238bceSAndroid Build Coastguard Worker     tcu::Mat3x2 m;
780*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1));
781*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1));
782*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2].swizzle(0, 1));
783*35238bceSAndroid Build Coastguard Worker     return m;
784*35238bceSAndroid Build Coastguard Worker }
785*35238bceSAndroid Build Coastguard Worker 
786*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)787*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3>(const ShaderEvalContext &evalCtx, int inputNdx)
788*35238bceSAndroid Build Coastguard Worker {
789*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
790*35238bceSAndroid Build Coastguard Worker     tcu::Mat3 m;
791*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1, 2));
792*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1, 2));
793*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2].swizzle(0, 1, 2));
794*35238bceSAndroid Build Coastguard Worker     return m;
795*35238bceSAndroid Build Coastguard Worker }
796*35238bceSAndroid Build Coastguard Worker 
797*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)798*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X4>(const ShaderEvalContext &evalCtx, int inputNdx)
799*35238bceSAndroid Build Coastguard Worker {
800*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
801*35238bceSAndroid Build Coastguard Worker     tcu::Mat3x4 m;
802*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0]);
803*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1]);
804*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2]);
805*35238bceSAndroid Build Coastguard Worker     return m;
806*35238bceSAndroid Build Coastguard Worker }
807*35238bceSAndroid Build Coastguard Worker 
808*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)809*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X2>(const ShaderEvalContext &evalCtx, int inputNdx)
810*35238bceSAndroid Build Coastguard Worker {
811*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
812*35238bceSAndroid Build Coastguard Worker     tcu::Mat4x2 m;
813*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1));
814*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1));
815*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2].swizzle(0, 1));
816*35238bceSAndroid Build Coastguard Worker     m.setColumn(3, evalCtx.in[3].swizzle(0, 1));
817*35238bceSAndroid Build Coastguard Worker     return m;
818*35238bceSAndroid Build Coastguard Worker }
819*35238bceSAndroid Build Coastguard Worker 
820*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)821*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X3>(const ShaderEvalContext &evalCtx, int inputNdx)
822*35238bceSAndroid Build Coastguard Worker {
823*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
824*35238bceSAndroid Build Coastguard Worker     tcu::Mat4x3 m;
825*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1, 2));
826*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1, 2));
827*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2].swizzle(0, 1, 2));
828*35238bceSAndroid Build Coastguard Worker     m.setColumn(3, evalCtx.in[3].swizzle(0, 1, 2));
829*35238bceSAndroid Build Coastguard Worker     return m;
830*35238bceSAndroid Build Coastguard Worker }
831*35238bceSAndroid Build Coastguard Worker 
832*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)833*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4>(const ShaderEvalContext &evalCtx, int inputNdx)
834*35238bceSAndroid Build Coastguard Worker {
835*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
836*35238bceSAndroid Build Coastguard Worker     tcu::Mat4 m;
837*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0]);
838*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1]);
839*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2]);
840*35238bceSAndroid Build Coastguard Worker     m.setColumn(3, evalCtx.in[3]);
841*35238bceSAndroid Build Coastguard Worker     return m;
842*35238bceSAndroid Build Coastguard Worker }
843*35238bceSAndroid Build Coastguard Worker 
844*35238bceSAndroid Build Coastguard Worker // Reduction from expression result to vec3.
845*35238bceSAndroid Build Coastguard Worker 
reduceToVec3(const tcu::Vec2 & value)846*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Vec2 &value)
847*35238bceSAndroid Build Coastguard Worker {
848*35238bceSAndroid Build Coastguard Worker     return value.swizzle(0, 1, 0);
849*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Vec3 & value)850*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Vec3 &value)
851*35238bceSAndroid Build Coastguard Worker {
852*35238bceSAndroid Build Coastguard Worker     return value;
853*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Vec4 & value)854*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Vec4 &value)
855*35238bceSAndroid Build Coastguard Worker {
856*35238bceSAndroid Build Coastguard Worker     return tcu::Vec3(value.x(), value.y(), value.z() + value.w());
857*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat2 & value)858*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat2 &value)
859*35238bceSAndroid Build Coastguard Worker {
860*35238bceSAndroid Build Coastguard Worker     return tcu::Vec3(value(0, 0), value(0, 1), value(1, 0) + value(1, 1));
861*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat2x3 & value)862*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat2x3 &value)
863*35238bceSAndroid Build Coastguard Worker {
864*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0) + value.getColumn(1);
865*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat2x4 & value)866*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat2x4 &value)
867*35238bceSAndroid Build Coastguard Worker {
868*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0).swizzle(0, 1, 2) + value.getColumn(1).swizzle(1, 2, 3);
869*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat3x2 & value)870*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat3x2 &value)
871*35238bceSAndroid Build Coastguard Worker {
872*35238bceSAndroid Build Coastguard Worker     return tcu::Vec3(value(0, 0) + value(1, 0), value(0, 1) + value(1, 1), value(0, 2) + value(1, 2));
873*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat3 & value)874*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat3 &value)
875*35238bceSAndroid Build Coastguard Worker {
876*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0) + value.getColumn(1) + value.getColumn(2);
877*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat3x4 & value)878*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat3x4 &value)
879*35238bceSAndroid Build Coastguard Worker {
880*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0).swizzle(0, 1, 2) + value.getColumn(1).swizzle(1, 2, 3) +
881*35238bceSAndroid Build Coastguard Worker            value.getColumn(2).swizzle(2, 3, 0);
882*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat4x2 & value)883*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat4x2 &value)
884*35238bceSAndroid Build Coastguard Worker {
885*35238bceSAndroid Build Coastguard Worker     return tcu::Vec3(value(0, 0) + value(1, 0) + value(0, 3), value(0, 1) + value(1, 1) + value(1, 3),
886*35238bceSAndroid Build Coastguard Worker                      value(0, 2) + value(1, 2));
887*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat4x3 & value)888*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat4x3 &value)
889*35238bceSAndroid Build Coastguard Worker {
890*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0) + value.getColumn(1) + value.getColumn(2) + value.getColumn(3);
891*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat4 & value)892*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat4 &value)
893*35238bceSAndroid Build Coastguard Worker {
894*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0).swizzle(0, 1, 2) + value.getColumn(1).swizzle(1, 2, 3) +
895*35238bceSAndroid Build Coastguard Worker            value.getColumn(2).swizzle(2, 3, 0) + value.getColumn(3).swizzle(3, 0, 1);
896*35238bceSAndroid Build Coastguard Worker }
897*35238bceSAndroid Build Coastguard Worker 
898*35238bceSAndroid Build Coastguard Worker // matrixCompMult
899*35238bceSAndroid Build Coastguard Worker 
900*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
matrixCompMult(const tcu::Matrix<T,Rows,Cols> & a,const tcu::Matrix<T,Rows,Cols> & b)901*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> matrixCompMult(const tcu::Matrix<T, Rows, Cols> &a, const tcu::Matrix<T, Rows, Cols> &b)
902*35238bceSAndroid Build Coastguard Worker {
903*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
904*35238bceSAndroid Build Coastguard Worker 
905*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
906*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
907*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = a(r, c) * b(r, c);
908*35238bceSAndroid Build Coastguard Worker 
909*35238bceSAndroid Build Coastguard Worker     return retVal;
910*35238bceSAndroid Build Coastguard Worker }
911*35238bceSAndroid Build Coastguard Worker 
912*35238bceSAndroid Build Coastguard Worker // outerProduct
913*35238bceSAndroid Build Coastguard Worker 
914*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
outerProduct(const tcu::Vector<T,Cols> & a,const tcu::Vector<T,Rows> & b)915*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Cols, Rows> outerProduct(const tcu::Vector<T, Cols> &a, const tcu::Vector<T, Rows> &b)
916*35238bceSAndroid Build Coastguard Worker {
917*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
918*35238bceSAndroid Build Coastguard Worker 
919*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
920*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
921*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = a[c] * b[r];
922*35238bceSAndroid Build Coastguard Worker 
923*35238bceSAndroid Build Coastguard Worker     return transpose(retVal); // to gl-form (column-major)
924*35238bceSAndroid Build Coastguard Worker }
925*35238bceSAndroid Build Coastguard Worker 
926*35238bceSAndroid Build Coastguard Worker // Determinant
927*35238bceSAndroid Build Coastguard Worker 
928*35238bceSAndroid Build Coastguard Worker template <int Size>
929*35238bceSAndroid Build Coastguard Worker float determinant(const tcu::Matrix<float, Size, Size> &mat);
930*35238bceSAndroid Build Coastguard Worker 
931*35238bceSAndroid Build Coastguard Worker template <>
determinant(const tcu::Matrix<float,2,2> & mat)932*35238bceSAndroid Build Coastguard Worker float determinant<2>(const tcu::Matrix<float, 2, 2> &mat)
933*35238bceSAndroid Build Coastguard Worker {
934*35238bceSAndroid Build Coastguard Worker     return mat(0, 0) * mat(1, 1) - mat(1, 0) * mat(0, 1);
935*35238bceSAndroid Build Coastguard Worker }
936*35238bceSAndroid Build Coastguard Worker 
937*35238bceSAndroid Build Coastguard Worker template <>
determinant(const tcu::Matrix<float,3,3> & mat)938*35238bceSAndroid Build Coastguard Worker float determinant<3>(const tcu::Matrix<float, 3, 3> &mat)
939*35238bceSAndroid Build Coastguard Worker {
940*35238bceSAndroid Build Coastguard Worker     return +mat(0, 0) * mat(1, 1) * mat(2, 2) + mat(0, 1) * mat(1, 2) * mat(2, 0) + mat(0, 2) * mat(1, 0) * mat(2, 1) -
941*35238bceSAndroid Build Coastguard Worker            mat(0, 0) * mat(1, 2) * mat(2, 1) - mat(0, 1) * mat(1, 0) * mat(2, 2) - mat(0, 2) * mat(1, 1) * mat(2, 0);
942*35238bceSAndroid Build Coastguard Worker }
943*35238bceSAndroid Build Coastguard Worker 
944*35238bceSAndroid Build Coastguard Worker template <>
determinant(const tcu::Matrix<float,4,4> & mat)945*35238bceSAndroid Build Coastguard Worker float determinant<4>(const tcu::Matrix<float, 4, 4> &mat)
946*35238bceSAndroid Build Coastguard Worker {
947*35238bceSAndroid Build Coastguard Worker     const float minorMatrices[4][3 * 3] = {{
948*35238bceSAndroid Build Coastguard Worker                                                mat(1, 1),
949*35238bceSAndroid Build Coastguard Worker                                                mat(2, 1),
950*35238bceSAndroid Build Coastguard Worker                                                mat(3, 1),
951*35238bceSAndroid Build Coastguard Worker                                                mat(1, 2),
952*35238bceSAndroid Build Coastguard Worker                                                mat(2, 2),
953*35238bceSAndroid Build Coastguard Worker                                                mat(3, 2),
954*35238bceSAndroid Build Coastguard Worker                                                mat(1, 3),
955*35238bceSAndroid Build Coastguard Worker                                                mat(2, 3),
956*35238bceSAndroid Build Coastguard Worker                                                mat(3, 3),
957*35238bceSAndroid Build Coastguard Worker                                            },
958*35238bceSAndroid Build Coastguard Worker                                            {
959*35238bceSAndroid Build Coastguard Worker                                                mat(1, 0),
960*35238bceSAndroid Build Coastguard Worker                                                mat(2, 0),
961*35238bceSAndroid Build Coastguard Worker                                                mat(3, 0),
962*35238bceSAndroid Build Coastguard Worker                                                mat(1, 2),
963*35238bceSAndroid Build Coastguard Worker                                                mat(2, 2),
964*35238bceSAndroid Build Coastguard Worker                                                mat(3, 2),
965*35238bceSAndroid Build Coastguard Worker                                                mat(1, 3),
966*35238bceSAndroid Build Coastguard Worker                                                mat(2, 3),
967*35238bceSAndroid Build Coastguard Worker                                                mat(3, 3),
968*35238bceSAndroid Build Coastguard Worker                                            },
969*35238bceSAndroid Build Coastguard Worker                                            {
970*35238bceSAndroid Build Coastguard Worker                                                mat(1, 0),
971*35238bceSAndroid Build Coastguard Worker                                                mat(2, 0),
972*35238bceSAndroid Build Coastguard Worker                                                mat(3, 0),
973*35238bceSAndroid Build Coastguard Worker                                                mat(1, 1),
974*35238bceSAndroid Build Coastguard Worker                                                mat(2, 1),
975*35238bceSAndroid Build Coastguard Worker                                                mat(3, 1),
976*35238bceSAndroid Build Coastguard Worker                                                mat(1, 3),
977*35238bceSAndroid Build Coastguard Worker                                                mat(2, 3),
978*35238bceSAndroid Build Coastguard Worker                                                mat(3, 3),
979*35238bceSAndroid Build Coastguard Worker                                            },
980*35238bceSAndroid Build Coastguard Worker                                            {
981*35238bceSAndroid Build Coastguard Worker                                                mat(1, 0),
982*35238bceSAndroid Build Coastguard Worker                                                mat(2, 0),
983*35238bceSAndroid Build Coastguard Worker                                                mat(3, 0),
984*35238bceSAndroid Build Coastguard Worker                                                mat(1, 1),
985*35238bceSAndroid Build Coastguard Worker                                                mat(2, 1),
986*35238bceSAndroid Build Coastguard Worker                                                mat(3, 1),
987*35238bceSAndroid Build Coastguard Worker                                                mat(1, 2),
988*35238bceSAndroid Build Coastguard Worker                                                mat(2, 2),
989*35238bceSAndroid Build Coastguard Worker                                                mat(3, 2),
990*35238bceSAndroid Build Coastguard Worker                                            }};
991*35238bceSAndroid Build Coastguard Worker 
992*35238bceSAndroid Build Coastguard Worker     return +mat(0, 0) * determinant(tcu::Mat3(minorMatrices[0])) -
993*35238bceSAndroid Build Coastguard Worker            mat(0, 1) * determinant(tcu::Mat3(minorMatrices[1])) + mat(0, 2) * determinant(tcu::Mat3(minorMatrices[2])) -
994*35238bceSAndroid Build Coastguard Worker            mat(0, 3) * determinant(tcu::Mat3(minorMatrices[3]));
995*35238bceSAndroid Build Coastguard Worker }
996*35238bceSAndroid Build Coastguard Worker 
997*35238bceSAndroid Build Coastguard Worker // Inverse
998*35238bceSAndroid Build Coastguard Worker 
999*35238bceSAndroid Build Coastguard Worker template <int Size>
1000*35238bceSAndroid Build Coastguard Worker tcu::Matrix<float, Size, Size> inverse(const tcu::Matrix<float, Size, Size> &mat);
1001*35238bceSAndroid Build Coastguard Worker 
1002*35238bceSAndroid Build Coastguard Worker template <>
inverse(const tcu::Matrix<float,2,2> & mat)1003*35238bceSAndroid Build Coastguard Worker tcu::Matrix<float, 2, 2> inverse<2>(const tcu::Matrix<float, 2, 2> &mat)
1004*35238bceSAndroid Build Coastguard Worker {
1005*35238bceSAndroid Build Coastguard Worker     const float det = determinant(mat);
1006*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<float, 2, 2> retVal;
1007*35238bceSAndroid Build Coastguard Worker 
1008*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(det != 0.0f);
1009*35238bceSAndroid Build Coastguard Worker 
1010*35238bceSAndroid Build Coastguard Worker     retVal(0, 0) = mat(1, 1) / det;
1011*35238bceSAndroid Build Coastguard Worker     retVal(0, 1) = -mat(0, 1) / det;
1012*35238bceSAndroid Build Coastguard Worker     retVal(1, 0) = -mat(1, 0) / det;
1013*35238bceSAndroid Build Coastguard Worker     retVal(1, 1) = mat(0, 0) / det;
1014*35238bceSAndroid Build Coastguard Worker 
1015*35238bceSAndroid Build Coastguard Worker     return retVal;
1016*35238bceSAndroid Build Coastguard Worker }
1017*35238bceSAndroid Build Coastguard Worker 
1018*35238bceSAndroid Build Coastguard Worker template <>
inverse(const tcu::Matrix<float,3,3> & mat)1019*35238bceSAndroid Build Coastguard Worker tcu::Matrix<float, 3, 3> inverse<3>(const tcu::Matrix<float, 3, 3> &mat)
1020*35238bceSAndroid Build Coastguard Worker {
1021*35238bceSAndroid Build Coastguard Worker     // Blockwise inversion
1022*35238bceSAndroid Build Coastguard Worker 
1023*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(determinant(mat) != 0.0f);
1024*35238bceSAndroid Build Coastguard Worker 
1025*35238bceSAndroid Build Coastguard Worker     const float areaA[2 * 2] = {mat(0, 0), mat(0, 1), mat(1, 0), mat(1, 1)};
1026*35238bceSAndroid Build Coastguard Worker     const float areaB[2]     = {
1027*35238bceSAndroid Build Coastguard Worker         mat(0, 2),
1028*35238bceSAndroid Build Coastguard Worker         mat(1, 2),
1029*35238bceSAndroid Build Coastguard Worker     };
1030*35238bceSAndroid Build Coastguard Worker     const float areaC[2] = {
1031*35238bceSAndroid Build Coastguard Worker         mat(2, 0),
1032*35238bceSAndroid Build Coastguard Worker         mat(2, 1),
1033*35238bceSAndroid Build Coastguard Worker     };
1034*35238bceSAndroid Build Coastguard Worker     const float areaD[1]     = {mat(2, 2)};
1035*35238bceSAndroid Build Coastguard Worker     const float nullField[4] = {0.0f};
1036*35238bceSAndroid Build Coastguard Worker 
1037*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> invA = inverse(tcu::Matrix<float, 2, 2>(areaA));
1038*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 1> matB = tcu::Matrix<float, 2, 1>(areaB);
1039*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 1, 2> matC = tcu::Matrix<float, 1, 2>(areaC);
1040*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 1, 1> matD = tcu::Matrix<float, 1, 1>(areaD);
1041*35238bceSAndroid Build Coastguard Worker 
1042*35238bceSAndroid Build Coastguard Worker     const float schurComplement            = 1.0f / (matD - matC * invA * matB)(0, 0);
1043*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> zeroMat = Mat2(nullField);
1044*35238bceSAndroid Build Coastguard Worker 
1045*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> blockA = invA + invA * matB * schurComplement * matC * invA;
1046*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 1> blockB = (zeroMat - invA) * matB * schurComplement;
1047*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 1, 2> blockC = matC * invA * (-schurComplement);
1048*35238bceSAndroid Build Coastguard Worker     const float blockD                    = schurComplement;
1049*35238bceSAndroid Build Coastguard Worker 
1050*35238bceSAndroid Build Coastguard Worker     const float result[3 * 3] = {
1051*35238bceSAndroid Build Coastguard Worker         blockA(0, 0), blockA(0, 1), blockB(0, 0), blockA(1, 0), blockA(1, 1),
1052*35238bceSAndroid Build Coastguard Worker         blockB(1, 0), blockC(0, 0), blockC(0, 1), blockD,
1053*35238bceSAndroid Build Coastguard Worker     };
1054*35238bceSAndroid Build Coastguard Worker 
1055*35238bceSAndroid Build Coastguard Worker     return Mat3(result);
1056*35238bceSAndroid Build Coastguard Worker }
1057*35238bceSAndroid Build Coastguard Worker 
1058*35238bceSAndroid Build Coastguard Worker template <>
inverse(const tcu::Matrix<float,4,4> & mat)1059*35238bceSAndroid Build Coastguard Worker tcu::Matrix<float, 4, 4> inverse<4>(const tcu::Matrix<float, 4, 4> &mat)
1060*35238bceSAndroid Build Coastguard Worker {
1061*35238bceSAndroid Build Coastguard Worker     // Blockwise inversion
1062*35238bceSAndroid Build Coastguard Worker 
1063*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(determinant(mat) != 0.0f);
1064*35238bceSAndroid Build Coastguard Worker 
1065*35238bceSAndroid Build Coastguard Worker     const float areaA[2 * 2] = {mat(0, 0), mat(0, 1), mat(1, 0), mat(1, 1)};
1066*35238bceSAndroid Build Coastguard Worker     const float areaB[2 * 2] = {mat(0, 2), mat(0, 3), mat(1, 2), mat(1, 3)};
1067*35238bceSAndroid Build Coastguard Worker     const float areaC[2 * 2] = {mat(2, 0), mat(2, 1), mat(3, 0), mat(3, 1)};
1068*35238bceSAndroid Build Coastguard Worker     const float areaD[2 * 2] = {mat(2, 2), mat(2, 3), mat(3, 2), mat(3, 3)};
1069*35238bceSAndroid Build Coastguard Worker     const float nullField[4] = {0.0f};
1070*35238bceSAndroid Build Coastguard Worker 
1071*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> invA = inverse(Mat2(areaA));
1072*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> matB = Mat2(areaB);
1073*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> matC = Mat2(areaC);
1074*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> matD = Mat2(areaD);
1075*35238bceSAndroid Build Coastguard Worker 
1076*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> schurComplement = inverse(matD - matC * invA * matB);
1077*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> zeroMat         = Mat2(nullField);
1078*35238bceSAndroid Build Coastguard Worker 
1079*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> blockA = invA + invA * matB * schurComplement * matC * invA;
1080*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> blockB = (zeroMat - invA) * matB * schurComplement;
1081*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> blockC = (zeroMat - schurComplement) * matC * invA;
1082*35238bceSAndroid Build Coastguard Worker     const tcu::Matrix<float, 2, 2> blockD = schurComplement;
1083*35238bceSAndroid Build Coastguard Worker 
1084*35238bceSAndroid Build Coastguard Worker     const float result[4 * 4] = {
1085*35238bceSAndroid Build Coastguard Worker         blockA(0, 0), blockA(0, 1), blockB(0, 0), blockB(0, 1), blockA(1, 0), blockA(1, 1), blockB(1, 0), blockB(1, 1),
1086*35238bceSAndroid Build Coastguard Worker         blockC(0, 0), blockC(0, 1), blockD(0, 0), blockD(0, 1), blockC(1, 0), blockC(1, 1), blockD(1, 0), blockD(1, 1),
1087*35238bceSAndroid Build Coastguard Worker     };
1088*35238bceSAndroid Build Coastguard Worker 
1089*35238bceSAndroid Build Coastguard Worker     return Mat4(result);
1090*35238bceSAndroid Build Coastguard Worker }
1091*35238bceSAndroid Build Coastguard Worker 
1092*35238bceSAndroid Build Coastguard Worker // negate
1093*35238bceSAndroid Build Coastguard Worker 
1094*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
negate(const tcu::Matrix<T,Rows,Cols> & mat)1095*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> negate(const tcu::Matrix<T, Rows, Cols> &mat)
1096*35238bceSAndroid Build Coastguard Worker {
1097*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
1098*35238bceSAndroid Build Coastguard Worker 
1099*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
1100*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
1101*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = -mat(r, c);
1102*35238bceSAndroid Build Coastguard Worker 
1103*35238bceSAndroid Build Coastguard Worker     return retVal;
1104*35238bceSAndroid Build Coastguard Worker }
1105*35238bceSAndroid Build Coastguard Worker 
1106*35238bceSAndroid Build Coastguard Worker // increment/decrement
1107*35238bceSAndroid Build Coastguard Worker 
1108*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
increment(const tcu::Matrix<T,Rows,Cols> & mat)1109*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> increment(const tcu::Matrix<T, Rows, Cols> &mat)
1110*35238bceSAndroid Build Coastguard Worker {
1111*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
1112*35238bceSAndroid Build Coastguard Worker 
1113*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
1114*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
1115*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = mat(r, c) + 1.0f;
1116*35238bceSAndroid Build Coastguard Worker 
1117*35238bceSAndroid Build Coastguard Worker     return retVal;
1118*35238bceSAndroid Build Coastguard Worker }
1119*35238bceSAndroid Build Coastguard Worker 
1120*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
decrement(const tcu::Matrix<T,Rows,Cols> & mat)1121*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> decrement(const tcu::Matrix<T, Rows, Cols> &mat)
1122*35238bceSAndroid Build Coastguard Worker {
1123*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
1124*35238bceSAndroid Build Coastguard Worker 
1125*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
1126*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
1127*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = mat(r, c) - 1.0f;
1128*35238bceSAndroid Build Coastguard Worker 
1129*35238bceSAndroid Build Coastguard Worker     return retVal;
1130*35238bceSAndroid Build Coastguard Worker }
1131*35238bceSAndroid Build Coastguard Worker 
1132*35238bceSAndroid Build Coastguard Worker // Evaluator template.
1133*35238bceSAndroid Build Coastguard Worker 
1134*35238bceSAndroid Build Coastguard Worker typedef void (*MatrixShaderEvalFunc)(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type);
1135*35238bceSAndroid Build Coastguard Worker 
1136*35238bceSAndroid Build Coastguard Worker template <int Op, int In0DataType, int In1DataType>
1137*35238bceSAndroid Build Coastguard Worker struct Evaluator;
1138*35238bceSAndroid Build Coastguard Worker 
1139*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1140*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_ADD, In0DataType, In1DataType>
1141*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1142*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1143*35238bceSAndroid Build Coastguard Worker     {
1144*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1145*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1146*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1147*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1148*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1149*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1150*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 + in1);
1151*35238bceSAndroid Build Coastguard Worker     }
1152*35238bceSAndroid Build Coastguard Worker };
1153*35238bceSAndroid Build Coastguard Worker 
1154*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1155*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_SUB, In0DataType, In1DataType>
1156*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1157*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1158*35238bceSAndroid Build Coastguard Worker     {
1159*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1160*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1161*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1162*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1163*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1164*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1165*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 - in1);
1166*35238bceSAndroid Build Coastguard Worker     }
1167*35238bceSAndroid Build Coastguard Worker };
1168*35238bceSAndroid Build Coastguard Worker 
1169*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1170*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_MUL, In0DataType, In1DataType>
1171*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1172*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1173*35238bceSAndroid Build Coastguard Worker     {
1174*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1175*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1176*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1177*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1178*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1179*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1180*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 * in1);
1181*35238bceSAndroid Build Coastguard Worker     }
1182*35238bceSAndroid Build Coastguard Worker };
1183*35238bceSAndroid Build Coastguard Worker 
1184*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1185*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_DIV, In0DataType, In1DataType>
1186*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1187*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1188*35238bceSAndroid Build Coastguard Worker     {
1189*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1190*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1191*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1192*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1193*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1194*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1195*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 / in1);
1196*35238bceSAndroid Build Coastguard Worker     }
1197*35238bceSAndroid Build Coastguard Worker };
1198*35238bceSAndroid Build Coastguard Worker 
1199*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1200*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_COMP_MUL, In0DataType, In1DataType>
1201*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1202*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1203*35238bceSAndroid Build Coastguard Worker     {
1204*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1205*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1206*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1207*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1208*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1209*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1210*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(matrixCompMult(in0, in1));
1211*35238bceSAndroid Build Coastguard Worker     }
1212*35238bceSAndroid Build Coastguard Worker };
1213*35238bceSAndroid Build Coastguard Worker 
1214*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1215*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_OUTER_PRODUCT, In0DataType, In1DataType>
1216*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1217*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1218*35238bceSAndroid Build Coastguard Worker     {
1219*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1220*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1221*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1222*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1223*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1224*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1225*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(outerProduct(in0, in1));
1226*35238bceSAndroid Build Coastguard Worker     }
1227*35238bceSAndroid Build Coastguard Worker };
1228*35238bceSAndroid Build Coastguard Worker 
1229*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1230*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_TRANSPOSE, In0DataType, In1DataType>
1231*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1232*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1233*35238bceSAndroid Build Coastguard Worker     {
1234*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1235*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1236*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1237*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1238*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(transpose(in0));
1239*35238bceSAndroid Build Coastguard Worker     }
1240*35238bceSAndroid Build Coastguard Worker };
1241*35238bceSAndroid Build Coastguard Worker 
1242*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1243*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_INVERSE, In0DataType, In1DataType>
1244*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1245*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1246*35238bceSAndroid Build Coastguard Worker     {
1247*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1248*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1249*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1250*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1251*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(inverse(in0));
1252*35238bceSAndroid Build Coastguard Worker     }
1253*35238bceSAndroid Build Coastguard Worker };
1254*35238bceSAndroid Build Coastguard Worker 
1255*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1256*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_DETERMINANT, In0DataType, In1DataType>
1257*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1258*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1259*35238bceSAndroid Build Coastguard Worker     {
1260*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1261*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1262*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1263*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1264*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = Vec3(determinant(in0));
1265*35238bceSAndroid Build Coastguard Worker     }
1266*35238bceSAndroid Build Coastguard Worker };
1267*35238bceSAndroid Build Coastguard Worker 
1268*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1269*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_UNARY_PLUS, In0DataType, In1DataType>
1270*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1271*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1272*35238bceSAndroid Build Coastguard Worker     {
1273*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1274*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1275*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1276*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1277*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0);
1278*35238bceSAndroid Build Coastguard Worker     }
1279*35238bceSAndroid Build Coastguard Worker };
1280*35238bceSAndroid Build Coastguard Worker 
1281*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1282*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_NEGATION, In0DataType, In1DataType>
1283*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1284*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1285*35238bceSAndroid Build Coastguard Worker     {
1286*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1287*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1288*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1289*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1290*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(negate(in0));
1291*35238bceSAndroid Build Coastguard Worker     }
1292*35238bceSAndroid Build Coastguard Worker };
1293*35238bceSAndroid Build Coastguard Worker 
1294*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1295*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_PRE_INCREMENT, In0DataType, In1DataType>
1296*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1297*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1298*35238bceSAndroid Build Coastguard Worker     {
1299*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1300*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1301*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1302*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1303*35238bceSAndroid Build Coastguard Worker 
1304*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
1305*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(increment(in0)) + reduceToVec3(increment(in0));
1306*35238bceSAndroid Build Coastguard Worker     }
1307*35238bceSAndroid Build Coastguard Worker };
1308*35238bceSAndroid Build Coastguard Worker 
1309*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1310*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_PRE_DECREMENT, In0DataType, In1DataType>
1311*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1312*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1313*35238bceSAndroid Build Coastguard Worker     {
1314*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1315*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1316*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1317*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1318*35238bceSAndroid Build Coastguard Worker 
1319*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
1320*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(decrement(in0)) + reduceToVec3(decrement(in0));
1321*35238bceSAndroid Build Coastguard Worker     }
1322*35238bceSAndroid Build Coastguard Worker };
1323*35238bceSAndroid Build Coastguard Worker 
1324*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1325*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_POST_INCREMENT, In0DataType, In1DataType>
1326*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1327*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1328*35238bceSAndroid Build Coastguard Worker     {
1329*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1330*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1331*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1332*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1333*35238bceSAndroid Build Coastguard Worker 
1334*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
1335*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(increment(in0));
1336*35238bceSAndroid Build Coastguard Worker     }
1337*35238bceSAndroid Build Coastguard Worker };
1338*35238bceSAndroid Build Coastguard Worker 
1339*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1340*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_POST_DECREMENT, In0DataType, In1DataType>
1341*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1342*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1343*35238bceSAndroid Build Coastguard Worker     {
1344*35238bceSAndroid Build Coastguard Worker         DE_UNREF(in1Type);
1345*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1346*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1347*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1348*35238bceSAndroid Build Coastguard Worker 
1349*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
1350*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(decrement(in0));
1351*35238bceSAndroid Build Coastguard Worker     }
1352*35238bceSAndroid Build Coastguard Worker };
1353*35238bceSAndroid Build Coastguard Worker 
1354*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1355*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_ADD_INTO, In0DataType, In1DataType>
1356*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1357*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1358*35238bceSAndroid Build Coastguard Worker     {
1359*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1360*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1361*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1362*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1363*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1364*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1365*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 + in1);
1366*35238bceSAndroid Build Coastguard Worker     }
1367*35238bceSAndroid Build Coastguard Worker };
1368*35238bceSAndroid Build Coastguard Worker 
1369*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1370*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_SUBTRACT_FROM, In0DataType, In1DataType>
1371*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1372*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1373*35238bceSAndroid Build Coastguard Worker     {
1374*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1375*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1376*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1377*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1378*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1379*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1380*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 - in1);
1381*35238bceSAndroid Build Coastguard Worker     }
1382*35238bceSAndroid Build Coastguard Worker };
1383*35238bceSAndroid Build Coastguard Worker 
1384*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1385*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_MULTIPLY_INTO, In0DataType, In1DataType>
1386*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1387*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1388*35238bceSAndroid Build Coastguard Worker     {
1389*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1390*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1391*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1392*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1393*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1394*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1395*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 * in1);
1396*35238bceSAndroid Build Coastguard Worker     }
1397*35238bceSAndroid Build Coastguard Worker };
1398*35238bceSAndroid Build Coastguard Worker 
1399*35238bceSAndroid Build Coastguard Worker template <int In0DataType, int In1DataType>
1400*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_DIVIDE_INTO, In0DataType, In1DataType>
1401*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles3::Functional::MatrixCaseUtils::Evaluator1402*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx, InputType in0Type, InputType in1Type)
1403*35238bceSAndroid Build Coastguard Worker     {
1404*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ?
1405*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0) :
1406*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1407*35238bceSAndroid Build Coastguard Worker         typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ?
1408*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1) :
1409*35238bceSAndroid Build Coastguard Worker                                                          getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1410*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz()                        = reduceToVec3(in0 / in1);
1411*35238bceSAndroid Build Coastguard Worker     }
1412*35238bceSAndroid Build Coastguard Worker };
1413*35238bceSAndroid Build Coastguard Worker 
getEvalFunc(const ShaderInput & in0,const ShaderInput & in1,MatrixOp op)1414*35238bceSAndroid Build Coastguard Worker MatrixShaderEvalFunc getEvalFunc(const ShaderInput &in0, const ShaderInput &in1, MatrixOp op)
1415*35238bceSAndroid Build Coastguard Worker {
1416*35238bceSAndroid Build Coastguard Worker     // Evaluator is selected based on op and input data types.
1417*35238bceSAndroid Build Coastguard Worker     // For efficient lookup the types and op enums are packed together to form a 19-bit key:
1418*35238bceSAndroid Build Coastguard Worker     // [18..14 OP] [13..7 TYPE0] [6..0 TYPE1]
1419*35238bceSAndroid Build Coastguard Worker 
1420*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(TYPE_LAST <= (1 << 7));
1421*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(OP_LAST <= (1 << 5));
1422*35238bceSAndroid Build Coastguard Worker 
1423*35238bceSAndroid Build Coastguard Worker #define PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE) (((OP) << 14) | ((IN0DATATYPE) << 7) | (IN1DATATYPE))
1424*35238bceSAndroid Build Coastguard Worker 
1425*35238bceSAndroid Build Coastguard Worker #define MAKE_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE)   \
1426*35238bceSAndroid Build Coastguard Worker     case PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE): \
1427*35238bceSAndroid Build Coastguard Worker         return Evaluator<OP, IN0DATATYPE, IN1DATATYPE>::evaluate
1428*35238bceSAndroid Build Coastguard Worker 
1429*35238bceSAndroid Build Coastguard Worker #define MAKE_SCALAR_OPS(IN0DATATYPE, IN1DATATYPE)     \
1430*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_ADD, IN0DATATYPE, IN1DATATYPE); \
1431*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_SUB, IN0DATATYPE, IN1DATATYPE); \
1432*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE); \
1433*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_DIV, IN0DATATYPE, IN1DATATYPE)
1434*35238bceSAndroid Build Coastguard Worker 
1435*35238bceSAndroid Build Coastguard Worker #define MAKE_CWISE_OPS(IN0DATATYPE, IN1DATATYPE)      \
1436*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_ADD, IN0DATATYPE, IN1DATATYPE); \
1437*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_SUB, IN0DATATYPE, IN1DATATYPE); \
1438*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_DIV, IN0DATATYPE, IN1DATATYPE); \
1439*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_COMP_MUL, IN0DATATYPE, IN1DATATYPE)
1440*35238bceSAndroid Build Coastguard Worker 
1441*35238bceSAndroid Build Coastguard Worker #define MAKE_MUL_OP(IN0DATATYPE, IN1DATATYPE) MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE)
1442*35238bceSAndroid Build Coastguard Worker 
1443*35238bceSAndroid Build Coastguard Worker #define MAKE_VECVEC_OP(IN0DATATYPE, IN1DATATYPE) MAKE_EVAL_CASE(OP_OUTER_PRODUCT, IN0DATATYPE, IN1DATATYPE)
1444*35238bceSAndroid Build Coastguard Worker 
1445*35238bceSAndroid Build Coastguard Worker #define MAKE_UNARY_OP(IN0DATATYPE)                             \
1446*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_TRANSPOSE, IN0DATATYPE, TYPE_LAST);      \
1447*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_UNARY_PLUS, IN0DATATYPE, TYPE_LAST);     \
1448*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_NEGATION, IN0DATATYPE, TYPE_LAST);       \
1449*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_PRE_INCREMENT, IN0DATATYPE, TYPE_LAST);  \
1450*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_PRE_DECREMENT, IN0DATATYPE, TYPE_LAST);  \
1451*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_POST_INCREMENT, IN0DATATYPE, TYPE_LAST); \
1452*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_POST_DECREMENT, IN0DATATYPE, TYPE_LAST)
1453*35238bceSAndroid Build Coastguard Worker 
1454*35238bceSAndroid Build Coastguard Worker #define MAKE_UNARY_SYMMETRIC_OP(IN0DATATYPE)                \
1455*35238bceSAndroid Build Coastguard Worker     MAKE_UNARY_OP(IN0DATATYPE);                             \
1456*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_DETERMINANT, IN0DATATYPE, TYPE_LAST); \
1457*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_INVERSE, IN0DATATYPE, TYPE_LAST)
1458*35238bceSAndroid Build Coastguard Worker 
1459*35238bceSAndroid Build Coastguard Worker #define MAKE_ASSIGNMENT_OP(IN0DATATYPE)                         \
1460*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_ADD_INTO, IN0DATATYPE, IN0DATATYPE);      \
1461*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_SUBTRACT_FROM, IN0DATATYPE, IN0DATATYPE); \
1462*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_DIVIDE_INTO, IN0DATATYPE, IN0DATATYPE)
1463*35238bceSAndroid Build Coastguard Worker 
1464*35238bceSAndroid Build Coastguard Worker #define MAKE_ASSIGNMENT_SYMMETRIC_OP(IN0DATATYPE) \
1465*35238bceSAndroid Build Coastguard Worker     MAKE_ASSIGNMENT_OP(IN0DATATYPE);              \
1466*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_MULTIPLY_INTO, IN0DATATYPE, IN0DATATYPE)
1467*35238bceSAndroid Build Coastguard Worker 
1468*35238bceSAndroid Build Coastguard Worker     switch (PACK_EVAL_CASE(op, in0.dataType, in1.dataType))
1469*35238bceSAndroid Build Coastguard Worker     {
1470*35238bceSAndroid Build Coastguard Worker         // Matrix-scalar.
1471*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2, TYPE_FLOAT);
1472*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X3, TYPE_FLOAT);
1473*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X4, TYPE_FLOAT);
1474*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X2, TYPE_FLOAT);
1475*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3, TYPE_FLOAT);
1476*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X4, TYPE_FLOAT);
1477*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X2, TYPE_FLOAT);
1478*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X3, TYPE_FLOAT);
1479*35238bceSAndroid Build Coastguard Worker         MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4, TYPE_FLOAT);
1480*35238bceSAndroid Build Coastguard Worker 
1481*35238bceSAndroid Build Coastguard Worker         // Matrix-vector.
1482*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_VEC2);
1483*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_VEC2);
1484*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_VEC2);
1485*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_VEC3);
1486*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_VEC3);
1487*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_VEC3);
1488*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_VEC4);
1489*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_VEC4);
1490*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_VEC4);
1491*35238bceSAndroid Build Coastguard Worker 
1492*35238bceSAndroid Build Coastguard Worker         // Vector-matrix.
1493*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT2);
1494*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT2X3);
1495*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT2X4);
1496*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT3X2);
1497*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT3);
1498*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT3X4);
1499*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT4X2);
1500*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT4X3);
1501*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT4);
1502*35238bceSAndroid Build Coastguard Worker 
1503*35238bceSAndroid Build Coastguard Worker         // Matrix-matrix.
1504*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT2);
1505*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT2);
1506*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT3X2);
1507*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT4X2);
1508*35238bceSAndroid Build Coastguard Worker 
1509*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT2X3);
1510*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT2);
1511*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT3X2);
1512*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT4X2);
1513*35238bceSAndroid Build Coastguard Worker 
1514*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT2X4);
1515*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT2);
1516*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT3X2);
1517*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT4X2);
1518*35238bceSAndroid Build Coastguard Worker 
1519*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT3X2);
1520*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT2X3);
1521*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT3);
1522*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT4X3);
1523*35238bceSAndroid Build Coastguard Worker 
1524*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT3);
1525*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT2X3);
1526*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT3);
1527*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT4X3);
1528*35238bceSAndroid Build Coastguard Worker 
1529*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT3X4);
1530*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT2X3);
1531*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT3);
1532*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT4X3);
1533*35238bceSAndroid Build Coastguard Worker 
1534*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT4X2);
1535*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT2X4);
1536*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT3X4);
1537*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT4);
1538*35238bceSAndroid Build Coastguard Worker 
1539*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT4X3);
1540*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT2X4);
1541*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT3X4);
1542*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT4);
1543*35238bceSAndroid Build Coastguard Worker 
1544*35238bceSAndroid Build Coastguard Worker         MAKE_CWISE_OPS(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT4);
1545*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT2X4);
1546*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT3X4);
1547*35238bceSAndroid Build Coastguard Worker         MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT4);
1548*35238bceSAndroid Build Coastguard Worker 
1549*35238bceSAndroid Build Coastguard Worker         // Vector-vector.
1550*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC2);
1551*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3);
1552*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC4);
1553*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC2);
1554*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC3);
1555*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4);
1556*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC2);
1557*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC3);
1558*35238bceSAndroid Build Coastguard Worker         MAKE_VECVEC_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4);
1559*35238bceSAndroid Build Coastguard Worker 
1560*35238bceSAndroid Build Coastguard Worker         // Unary Matrix.
1561*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
1562*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_OP(TYPE_FLOAT_MAT2X3);
1563*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_OP(TYPE_FLOAT_MAT2X4);
1564*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_OP(TYPE_FLOAT_MAT3X2);
1565*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
1566*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_OP(TYPE_FLOAT_MAT3X4);
1567*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_OP(TYPE_FLOAT_MAT4X2);
1568*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_OP(TYPE_FLOAT_MAT4X3);
1569*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT4);
1570*35238bceSAndroid Build Coastguard Worker 
1571*35238bceSAndroid Build Coastguard Worker         // Assignments
1572*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
1573*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X3);
1574*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X4);
1575*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X2);
1576*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
1577*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X4);
1578*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X2);
1579*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X3);
1580*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT4);
1581*35238bceSAndroid Build Coastguard Worker 
1582*35238bceSAndroid Build Coastguard Worker     default:
1583*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1584*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
1585*35238bceSAndroid Build Coastguard Worker     }
1586*35238bceSAndroid Build Coastguard Worker 
1587*35238bceSAndroid Build Coastguard Worker #undef PACK_EVAL_CASE
1588*35238bceSAndroid Build Coastguard Worker #undef MAKE_EVAL_CASE
1589*35238bceSAndroid Build Coastguard Worker #undef MUL_OP
1590*35238bceSAndroid Build Coastguard Worker #undef ALL_OPS
1591*35238bceSAndroid Build Coastguard Worker #undef MAKE_MAT_SCALAR_VEC_CASES
1592*35238bceSAndroid Build Coastguard Worker #undef MAKE_MAT_MAT_CASES
1593*35238bceSAndroid Build Coastguard Worker }
1594*35238bceSAndroid Build Coastguard Worker 
1595*35238bceSAndroid Build Coastguard Worker // Shader source format utilities.
1596*35238bceSAndroid Build Coastguard Worker 
1597*35238bceSAndroid Build Coastguard Worker template <int Size>
writeVectorConstructor(std::ostream & str,const tcu::Vector<float,Size> & v)1598*35238bceSAndroid Build Coastguard Worker void writeVectorConstructor(std::ostream &str, const tcu::Vector<float, Size> &v)
1599*35238bceSAndroid Build Coastguard Worker {
1600*35238bceSAndroid Build Coastguard Worker     str << "vec" << Size << "(";
1601*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < Size; ndx++)
1602*35238bceSAndroid Build Coastguard Worker     {
1603*35238bceSAndroid Build Coastguard Worker         if (ndx != 0)
1604*35238bceSAndroid Build Coastguard Worker             str << ", ";
1605*35238bceSAndroid Build Coastguard Worker         str << de::floatToString(v[ndx], 1);
1606*35238bceSAndroid Build Coastguard Worker     }
1607*35238bceSAndroid Build Coastguard Worker     str << ")";
1608*35238bceSAndroid Build Coastguard Worker }
1609*35238bceSAndroid Build Coastguard Worker 
1610*35238bceSAndroid Build Coastguard Worker template <int Cols, int Rows>
writeMatrixConstructor(std::ostream & str,const tcu::Matrix<float,Rows,Cols> & m)1611*35238bceSAndroid Build Coastguard Worker void writeMatrixConstructor(std::ostream &str, const tcu::Matrix<float, Rows, Cols> &m)
1612*35238bceSAndroid Build Coastguard Worker {
1613*35238bceSAndroid Build Coastguard Worker     if (Rows == Cols)
1614*35238bceSAndroid Build Coastguard Worker         str << "mat" << Cols;
1615*35238bceSAndroid Build Coastguard Worker     else
1616*35238bceSAndroid Build Coastguard Worker         str << "mat" << Cols << "x" << Rows;
1617*35238bceSAndroid Build Coastguard Worker 
1618*35238bceSAndroid Build Coastguard Worker     str << "(";
1619*35238bceSAndroid Build Coastguard Worker     for (int colNdx = 0; colNdx < Cols; colNdx++)
1620*35238bceSAndroid Build Coastguard Worker     {
1621*35238bceSAndroid Build Coastguard Worker         for (int rowNdx = 0; rowNdx < Rows; rowNdx++)
1622*35238bceSAndroid Build Coastguard Worker         {
1623*35238bceSAndroid Build Coastguard Worker             if (rowNdx > 0 || colNdx > 0)
1624*35238bceSAndroid Build Coastguard Worker                 str << ", ";
1625*35238bceSAndroid Build Coastguard Worker             str << de::floatToString(m(rowNdx, colNdx), 1);
1626*35238bceSAndroid Build Coastguard Worker         }
1627*35238bceSAndroid Build Coastguard Worker     }
1628*35238bceSAndroid Build Coastguard Worker     str << ")";
1629*35238bceSAndroid Build Coastguard Worker }
1630*35238bceSAndroid Build Coastguard Worker 
1631*35238bceSAndroid Build Coastguard Worker } // namespace MatrixCaseUtils
1632*35238bceSAndroid Build Coastguard Worker 
1633*35238bceSAndroid Build Coastguard Worker using namespace MatrixCaseUtils;
1634*35238bceSAndroid Build Coastguard Worker 
1635*35238bceSAndroid Build Coastguard Worker class MatrixShaderEvaluator : public ShaderEvaluator
1636*35238bceSAndroid Build Coastguard Worker {
1637*35238bceSAndroid Build Coastguard Worker public:
1638*35238bceSAndroid Build Coastguard Worker     MatrixShaderEvaluator(MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1);
1639*35238bceSAndroid Build Coastguard Worker 
1640*35238bceSAndroid Build Coastguard Worker     virtual void evaluate(ShaderEvalContext &evalCtx);
1641*35238bceSAndroid Build Coastguard Worker 
1642*35238bceSAndroid Build Coastguard Worker private:
1643*35238bceSAndroid Build Coastguard Worker     MatrixShaderEvalFunc m_matEvalFunc;
1644*35238bceSAndroid Build Coastguard Worker     InputType m_inType0;
1645*35238bceSAndroid Build Coastguard Worker     InputType m_inType1;
1646*35238bceSAndroid Build Coastguard Worker };
1647*35238bceSAndroid Build Coastguard Worker 
MatrixShaderEvaluator(MatrixShaderEvalFunc evalFunc,InputType inType0,InputType inType1)1648*35238bceSAndroid Build Coastguard Worker MatrixShaderEvaluator::MatrixShaderEvaluator(MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1)
1649*35238bceSAndroid Build Coastguard Worker     : m_matEvalFunc(evalFunc)
1650*35238bceSAndroid Build Coastguard Worker     , m_inType0(inType0)
1651*35238bceSAndroid Build Coastguard Worker     , m_inType1(inType1)
1652*35238bceSAndroid Build Coastguard Worker {
1653*35238bceSAndroid Build Coastguard Worker }
1654*35238bceSAndroid Build Coastguard Worker 
evaluate(ShaderEvalContext & evalCtx)1655*35238bceSAndroid Build Coastguard Worker void MatrixShaderEvaluator::evaluate(ShaderEvalContext &evalCtx)
1656*35238bceSAndroid Build Coastguard Worker {
1657*35238bceSAndroid Build Coastguard Worker     m_matEvalFunc(evalCtx, m_inType0, m_inType1);
1658*35238bceSAndroid Build Coastguard Worker }
1659*35238bceSAndroid Build Coastguard Worker 
1660*35238bceSAndroid Build Coastguard Worker class ShaderMatrixCase : public ShaderRenderCase
1661*35238bceSAndroid Build Coastguard Worker {
1662*35238bceSAndroid Build Coastguard Worker public:
1663*35238bceSAndroid Build Coastguard Worker     ShaderMatrixCase(Context &context, const char *name, const char *desc, const ShaderInput &in0,
1664*35238bceSAndroid Build Coastguard Worker                      const ShaderInput &in1, MatrixOp op, bool isVertexCase);
1665*35238bceSAndroid Build Coastguard Worker     ~ShaderMatrixCase(void);
1666*35238bceSAndroid Build Coastguard Worker 
1667*35238bceSAndroid Build Coastguard Worker     void init(void);
1668*35238bceSAndroid Build Coastguard Worker 
1669*35238bceSAndroid Build Coastguard Worker protected:
1670*35238bceSAndroid Build Coastguard Worker     std::string genGLSLMatToVec3Reduction(const glu::DataType &matType, const char *varName);
1671*35238bceSAndroid Build Coastguard Worker     void setupUniforms(int programID, const tcu::Vec4 &constCoords);
1672*35238bceSAndroid Build Coastguard Worker 
1673*35238bceSAndroid Build Coastguard Worker private:
1674*35238bceSAndroid Build Coastguard Worker     ShaderInput m_in0;
1675*35238bceSAndroid Build Coastguard Worker     ShaderInput m_in1;
1676*35238bceSAndroid Build Coastguard Worker     MatrixOp m_op;
1677*35238bceSAndroid Build Coastguard Worker     MatrixShaderEvaluator m_matEvaluator;
1678*35238bceSAndroid Build Coastguard Worker };
1679*35238bceSAndroid Build Coastguard Worker 
ShaderMatrixCase(Context & context,const char * name,const char * desc,const ShaderInput & in0,const ShaderInput & in1,MatrixOp op,bool isVertexCase)1680*35238bceSAndroid Build Coastguard Worker ShaderMatrixCase::ShaderMatrixCase(Context &context, const char *name, const char *desc, const ShaderInput &in0,
1681*35238bceSAndroid Build Coastguard Worker                                    const ShaderInput &in1, MatrixOp op, bool isVertexCase)
1682*35238bceSAndroid Build Coastguard Worker     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc,
1683*35238bceSAndroid Build Coastguard Worker                        isVertexCase, m_matEvaluator)
1684*35238bceSAndroid Build Coastguard Worker     , m_in0(in0)
1685*35238bceSAndroid Build Coastguard Worker     , m_in1(in1)
1686*35238bceSAndroid Build Coastguard Worker     , m_op(op)
1687*35238bceSAndroid Build Coastguard Worker     , m_matEvaluator(getEvalFunc(in0, in1, op), in0.inputType, in1.inputType)
1688*35238bceSAndroid Build Coastguard Worker {
1689*35238bceSAndroid Build Coastguard Worker }
1690*35238bceSAndroid Build Coastguard Worker 
~ShaderMatrixCase(void)1691*35238bceSAndroid Build Coastguard Worker ShaderMatrixCase::~ShaderMatrixCase(void)
1692*35238bceSAndroid Build Coastguard Worker {
1693*35238bceSAndroid Build Coastguard Worker }
1694*35238bceSAndroid Build Coastguard Worker 
init(void)1695*35238bceSAndroid Build Coastguard Worker void ShaderMatrixCase::init(void)
1696*35238bceSAndroid Build Coastguard Worker {
1697*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
1698*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
1699*35238bceSAndroid Build Coastguard Worker     std::ostringstream &op = m_isVertexCase ? vtx : frag;
1700*35238bceSAndroid Build Coastguard Worker 
1701*35238bceSAndroid Build Coastguard Worker     bool isInDynMat0 = isDataTypeMatrix(m_in0.dataType) && m_in0.inputType == INPUTTYPE_DYNAMIC;
1702*35238bceSAndroid Build Coastguard Worker     bool isInDynMat1 = isDataTypeMatrix(m_in1.dataType) && m_in1.inputType == INPUTTYPE_DYNAMIC;
1703*35238bceSAndroid Build Coastguard Worker     string inValue0;
1704*35238bceSAndroid Build Coastguard Worker     string inValue1;
1705*35238bceSAndroid Build Coastguard Worker     DataType resultType  = TYPE_LAST;
1706*35238bceSAndroid Build Coastguard Worker     Precision resultPrec = m_in0.precision;
1707*35238bceSAndroid Build Coastguard Worker     vector<string> passVars;
1708*35238bceSAndroid Build Coastguard Worker     int numInputs = (isOperationBinary(m_op)) ? (2) : (1);
1709*35238bceSAndroid Build Coastguard Worker 
1710*35238bceSAndroid Build Coastguard Worker     std::string operationValue0;
1711*35238bceSAndroid Build Coastguard Worker     std::string operationValue1;
1712*35238bceSAndroid Build Coastguard Worker 
1713*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!isInDynMat0 || !isInDynMat1); // Only single dynamic matrix input is allowed.
1714*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isInDynMat0 && isInDynMat1);
1715*35238bceSAndroid Build Coastguard Worker 
1716*35238bceSAndroid Build Coastguard Worker     // Compute result type.
1717*35238bceSAndroid Build Coastguard Worker     if (m_op == OP_MUL && isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
1718*35238bceSAndroid Build Coastguard Worker     {
1719*35238bceSAndroid Build Coastguard Worker         resultType =
1720*35238bceSAndroid Build Coastguard Worker             getDataTypeMatrix(getDataTypeMatrixNumColumns(m_in1.dataType), getDataTypeMatrixNumRows(m_in0.dataType));
1721*35238bceSAndroid Build Coastguard Worker     }
1722*35238bceSAndroid Build Coastguard Worker     else if (m_op == OP_OUTER_PRODUCT)
1723*35238bceSAndroid Build Coastguard Worker     {
1724*35238bceSAndroid Build Coastguard Worker         resultType = getDataTypeMatrix(getDataTypeScalarSize(m_in1.dataType), getDataTypeScalarSize(m_in0.dataType));
1725*35238bceSAndroid Build Coastguard Worker     }
1726*35238bceSAndroid Build Coastguard Worker     else if (m_op == OP_TRANSPOSE)
1727*35238bceSAndroid Build Coastguard Worker     {
1728*35238bceSAndroid Build Coastguard Worker         resultType =
1729*35238bceSAndroid Build Coastguard Worker             getDataTypeMatrix(getDataTypeMatrixNumRows(m_in0.dataType), getDataTypeMatrixNumColumns(m_in0.dataType));
1730*35238bceSAndroid Build Coastguard Worker     }
1731*35238bceSAndroid Build Coastguard Worker     else if (m_op == OP_INVERSE)
1732*35238bceSAndroid Build Coastguard Worker     {
1733*35238bceSAndroid Build Coastguard Worker         resultType = m_in0.dataType;
1734*35238bceSAndroid Build Coastguard Worker     }
1735*35238bceSAndroid Build Coastguard Worker     else if (m_op == OP_DETERMINANT)
1736*35238bceSAndroid Build Coastguard Worker     {
1737*35238bceSAndroid Build Coastguard Worker         resultType = TYPE_FLOAT;
1738*35238bceSAndroid Build Coastguard Worker     }
1739*35238bceSAndroid Build Coastguard Worker     else if (getOperationType(m_op) == OPERATIONTYPE_UNARY_PREFIX_OPERATOR ||
1740*35238bceSAndroid Build Coastguard Worker              getOperationType(m_op) == OPERATIONTYPE_UNARY_POSTFIX_OPERATOR)
1741*35238bceSAndroid Build Coastguard Worker     {
1742*35238bceSAndroid Build Coastguard Worker         resultType = m_in0.dataType;
1743*35238bceSAndroid Build Coastguard Worker     }
1744*35238bceSAndroid Build Coastguard Worker     else if (isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
1745*35238bceSAndroid Build Coastguard Worker     {
1746*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_in0.dataType == m_in1.dataType);
1747*35238bceSAndroid Build Coastguard Worker         resultType = m_in0.dataType;
1748*35238bceSAndroid Build Coastguard Worker     }
1749*35238bceSAndroid Build Coastguard Worker     else if (isDataTypeMatrix(m_in0.dataType) || isDataTypeMatrix(m_in1.dataType))
1750*35238bceSAndroid Build Coastguard Worker     {
1751*35238bceSAndroid Build Coastguard Worker         int matNdx          = isDataTypeMatrix(m_in0.dataType) ? 0 : 1;
1752*35238bceSAndroid Build Coastguard Worker         DataType matrixType = matNdx == 0 ? m_in0.dataType : m_in1.dataType;
1753*35238bceSAndroid Build Coastguard Worker         DataType otherType  = matNdx == 0 ? m_in1.dataType : m_in0.dataType;
1754*35238bceSAndroid Build Coastguard Worker 
1755*35238bceSAndroid Build Coastguard Worker         if (otherType == TYPE_FLOAT)
1756*35238bceSAndroid Build Coastguard Worker             resultType = matrixType;
1757*35238bceSAndroid Build Coastguard Worker         else
1758*35238bceSAndroid Build Coastguard Worker         {
1759*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(isDataTypeVector(otherType));
1760*35238bceSAndroid Build Coastguard Worker             resultType = getDataTypeFloatVec(matNdx == 0 ? getDataTypeMatrixNumRows(matrixType) :
1761*35238bceSAndroid Build Coastguard Worker                                                            getDataTypeMatrixNumColumns(matrixType));
1762*35238bceSAndroid Build Coastguard Worker         }
1763*35238bceSAndroid Build Coastguard Worker     }
1764*35238bceSAndroid Build Coastguard Worker     else
1765*35238bceSAndroid Build Coastguard Worker     {
1766*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1767*35238bceSAndroid Build Coastguard Worker     }
1768*35238bceSAndroid Build Coastguard Worker 
1769*35238bceSAndroid Build Coastguard Worker     vtx << "#version 300 es\n";
1770*35238bceSAndroid Build Coastguard Worker     frag << "#version 300 es\n";
1771*35238bceSAndroid Build Coastguard Worker 
1772*35238bceSAndroid Build Coastguard Worker     vtx << "in highp vec4 a_position;\n";
1773*35238bceSAndroid Build Coastguard Worker     frag << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
1774*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
1775*35238bceSAndroid Build Coastguard Worker     {
1776*35238bceSAndroid Build Coastguard Worker         vtx << "out mediump vec4 v_color;\n";
1777*35238bceSAndroid Build Coastguard Worker         frag << "in mediump vec4 v_color;\n";
1778*35238bceSAndroid Build Coastguard Worker     }
1779*35238bceSAndroid Build Coastguard Worker 
1780*35238bceSAndroid Build Coastguard Worker     // Input declarations.
1781*35238bceSAndroid Build Coastguard Worker     for (int inNdx = 0; inNdx < numInputs; inNdx++)
1782*35238bceSAndroid Build Coastguard Worker     {
1783*35238bceSAndroid Build Coastguard Worker         const ShaderInput &in = inNdx > 0 ? m_in1 : m_in0;
1784*35238bceSAndroid Build Coastguard Worker         const char *precName  = getPrecisionName(in.precision);
1785*35238bceSAndroid Build Coastguard Worker         const char *typeName  = getDataTypeName(in.dataType);
1786*35238bceSAndroid Build Coastguard Worker         string &inValue       = inNdx > 0 ? inValue1 : inValue0;
1787*35238bceSAndroid Build Coastguard Worker 
1788*35238bceSAndroid Build Coastguard Worker         if (in.inputType == INPUTTYPE_DYNAMIC)
1789*35238bceSAndroid Build Coastguard Worker         {
1790*35238bceSAndroid Build Coastguard Worker             vtx << "in " << precName << " " << typeName << " a_";
1791*35238bceSAndroid Build Coastguard Worker 
1792*35238bceSAndroid Build Coastguard Worker             if (isDataTypeMatrix(in.dataType))
1793*35238bceSAndroid Build Coastguard Worker             {
1794*35238bceSAndroid Build Coastguard Worker                 // a_matN, v_matN
1795*35238bceSAndroid Build Coastguard Worker                 vtx << typeName << ";\n";
1796*35238bceSAndroid Build Coastguard Worker                 if (!m_isVertexCase)
1797*35238bceSAndroid Build Coastguard Worker                 {
1798*35238bceSAndroid Build Coastguard Worker                     vtx << "out " << precName << " " << typeName << " v_" << typeName << ";\n";
1799*35238bceSAndroid Build Coastguard Worker                     frag << "in " << precName << " " << typeName << " v_" << typeName << ";\n";
1800*35238bceSAndroid Build Coastguard Worker                     passVars.push_back(typeName);
1801*35238bceSAndroid Build Coastguard Worker                 }
1802*35238bceSAndroid Build Coastguard Worker 
1803*35238bceSAndroid Build Coastguard Worker                 inValue = string(m_isVertexCase ? "a_" : "v_") + getDataTypeName(in.dataType);
1804*35238bceSAndroid Build Coastguard Worker             }
1805*35238bceSAndroid Build Coastguard Worker             else
1806*35238bceSAndroid Build Coastguard Worker             {
1807*35238bceSAndroid Build Coastguard Worker                 // a_coords, v_coords
1808*35238bceSAndroid Build Coastguard Worker                 vtx << "coords;\n";
1809*35238bceSAndroid Build Coastguard Worker                 if (!m_isVertexCase)
1810*35238bceSAndroid Build Coastguard Worker                 {
1811*35238bceSAndroid Build Coastguard Worker                     vtx << "out " << precName << " " << typeName << " v_coords;\n";
1812*35238bceSAndroid Build Coastguard Worker                     frag << "in " << precName << " " << typeName << " v_coords;\n";
1813*35238bceSAndroid Build Coastguard Worker                     passVars.push_back("coords");
1814*35238bceSAndroid Build Coastguard Worker                 }
1815*35238bceSAndroid Build Coastguard Worker 
1816*35238bceSAndroid Build Coastguard Worker                 inValue = m_isVertexCase ? "a_coords" : "v_coords";
1817*35238bceSAndroid Build Coastguard Worker             }
1818*35238bceSAndroid Build Coastguard Worker         }
1819*35238bceSAndroid Build Coastguard Worker         else if (in.inputType == INPUTTYPE_UNIFORM)
1820*35238bceSAndroid Build Coastguard Worker         {
1821*35238bceSAndroid Build Coastguard Worker             op << "uniform " << precName << " " << typeName << " u_in" << inNdx << ";\n";
1822*35238bceSAndroid Build Coastguard Worker             inValue = string("u_in") + de::toString(inNdx);
1823*35238bceSAndroid Build Coastguard Worker         }
1824*35238bceSAndroid Build Coastguard Worker         else if (in.inputType == INPUTTYPE_CONST)
1825*35238bceSAndroid Build Coastguard Worker         {
1826*35238bceSAndroid Build Coastguard Worker             op << "const " << precName << " " << typeName << " in" << inNdx << " = ";
1827*35238bceSAndroid Build Coastguard Worker 
1828*35238bceSAndroid Build Coastguard Worker             // Generate declaration.
1829*35238bceSAndroid Build Coastguard Worker             switch (in.dataType)
1830*35238bceSAndroid Build Coastguard Worker             {
1831*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT:
1832*35238bceSAndroid Build Coastguard Worker                 op << de::floatToString(s_constInFloat[inNdx], 1);
1833*35238bceSAndroid Build Coastguard Worker                 break;
1834*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC2:
1835*35238bceSAndroid Build Coastguard Worker                 writeVectorConstructor<2>(op, s_constInVec2[inNdx]);
1836*35238bceSAndroid Build Coastguard Worker                 break;
1837*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC3:
1838*35238bceSAndroid Build Coastguard Worker                 writeVectorConstructor<3>(op, s_constInVec3[inNdx]);
1839*35238bceSAndroid Build Coastguard Worker                 break;
1840*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC4:
1841*35238bceSAndroid Build Coastguard Worker                 writeVectorConstructor<4>(op, s_constInVec4[inNdx]);
1842*35238bceSAndroid Build Coastguard Worker                 break;
1843*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2:
1844*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<2, 2>(op, Mat2(s_constInMat2x2[inNdx]));
1845*35238bceSAndroid Build Coastguard Worker                 break;
1846*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2X3:
1847*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<2, 3>(op, Mat2x3(s_constInMat2x3[inNdx]));
1848*35238bceSAndroid Build Coastguard Worker                 break;
1849*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2X4:
1850*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<2, 4>(op, Mat2x4(s_constInMat2x4[inNdx]));
1851*35238bceSAndroid Build Coastguard Worker                 break;
1852*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3X2:
1853*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<3, 2>(op, Mat3x2(s_constInMat3x2[inNdx]));
1854*35238bceSAndroid Build Coastguard Worker                 break;
1855*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3:
1856*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<3, 3>(op, Mat3(s_constInMat3x3[inNdx]));
1857*35238bceSAndroid Build Coastguard Worker                 break;
1858*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3X4:
1859*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<3, 4>(op, Mat3x4(s_constInMat3x4[inNdx]));
1860*35238bceSAndroid Build Coastguard Worker                 break;
1861*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4X2:
1862*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<4, 2>(op, Mat4x2(s_constInMat4x2[inNdx]));
1863*35238bceSAndroid Build Coastguard Worker                 break;
1864*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4X3:
1865*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<4, 3>(op, Mat4x3(s_constInMat4x3[inNdx]));
1866*35238bceSAndroid Build Coastguard Worker                 break;
1867*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4:
1868*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<4, 4>(op, Mat4(s_constInMat4x4[inNdx]));
1869*35238bceSAndroid Build Coastguard Worker                 break;
1870*35238bceSAndroid Build Coastguard Worker 
1871*35238bceSAndroid Build Coastguard Worker             default:
1872*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1873*35238bceSAndroid Build Coastguard Worker             }
1874*35238bceSAndroid Build Coastguard Worker 
1875*35238bceSAndroid Build Coastguard Worker             op << ";\n";
1876*35238bceSAndroid Build Coastguard Worker 
1877*35238bceSAndroid Build Coastguard Worker             inValue = string("in") + de::toString(inNdx);
1878*35238bceSAndroid Build Coastguard Worker         }
1879*35238bceSAndroid Build Coastguard Worker     }
1880*35238bceSAndroid Build Coastguard Worker 
1881*35238bceSAndroid Build Coastguard Worker     vtx << "\n"
1882*35238bceSAndroid Build Coastguard Worker         << "void main (void)\n"
1883*35238bceSAndroid Build Coastguard Worker         << "{\n"
1884*35238bceSAndroid Build Coastguard Worker         << "    gl_Position = a_position;\n";
1885*35238bceSAndroid Build Coastguard Worker     frag << "\n"
1886*35238bceSAndroid Build Coastguard Worker          << "void main (void)\n"
1887*35238bceSAndroid Build Coastguard Worker          << "{\n";
1888*35238bceSAndroid Build Coastguard Worker 
1889*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
1890*35238bceSAndroid Build Coastguard Worker         frag << "    dEQP_FragColor = v_color;\n";
1891*35238bceSAndroid Build Coastguard Worker     else
1892*35238bceSAndroid Build Coastguard Worker     {
1893*35238bceSAndroid Build Coastguard Worker         for (vector<string>::const_iterator copyIter = passVars.begin(); copyIter != passVars.end(); copyIter++)
1894*35238bceSAndroid Build Coastguard Worker             vtx << "    v_" << *copyIter << " = "
1895*35238bceSAndroid Build Coastguard Worker                 << "a_" << *copyIter << ";\n";
1896*35238bceSAndroid Build Coastguard Worker     }
1897*35238bceSAndroid Build Coastguard Worker 
1898*35238bceSAndroid Build Coastguard Worker     // Operation.
1899*35238bceSAndroid Build Coastguard Worker 
1900*35238bceSAndroid Build Coastguard Worker     switch (getOperationNature(m_op))
1901*35238bceSAndroid Build Coastguard Worker     {
1902*35238bceSAndroid Build Coastguard Worker     case OPERATIONNATURE_PURE:
1903*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
1904*35238bceSAndroid Build Coastguard Worker 
1905*35238bceSAndroid Build Coastguard Worker         operationValue0 = inValue0;
1906*35238bceSAndroid Build Coastguard Worker         operationValue1 = inValue1;
1907*35238bceSAndroid Build Coastguard Worker         break;
1908*35238bceSAndroid Build Coastguard Worker 
1909*35238bceSAndroid Build Coastguard Worker     case OPERATIONNATURE_MUTATING:
1910*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
1911*35238bceSAndroid Build Coastguard Worker 
1912*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " tmpValue = " << inValue0
1913*35238bceSAndroid Build Coastguard Worker            << ";\n";
1914*35238bceSAndroid Build Coastguard Worker 
1915*35238bceSAndroid Build Coastguard Worker         operationValue0 = "tmpValue";
1916*35238bceSAndroid Build Coastguard Worker         operationValue1 = inValue1;
1917*35238bceSAndroid Build Coastguard Worker         break;
1918*35238bceSAndroid Build Coastguard Worker 
1919*35238bceSAndroid Build Coastguard Worker     case OPERATIONNATURE_ASSIGNMENT:
1920*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(getOperationType(m_op) == OPERATIONTYPE_ASSIGNMENT);
1921*35238bceSAndroid Build Coastguard Worker 
1922*35238bceSAndroid Build Coastguard Worker         operationValue0 = inValue0;
1923*35238bceSAndroid Build Coastguard Worker         operationValue1 = inValue1;
1924*35238bceSAndroid Build Coastguard Worker         break;
1925*35238bceSAndroid Build Coastguard Worker 
1926*35238bceSAndroid Build Coastguard Worker     default:
1927*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1928*35238bceSAndroid Build Coastguard Worker     }
1929*35238bceSAndroid Build Coastguard Worker 
1930*35238bceSAndroid Build Coastguard Worker     switch (getOperationType(m_op))
1931*35238bceSAndroid Build Coastguard Worker     {
1932*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_BINARY_OPERATOR:
1933*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1934*35238bceSAndroid Build Coastguard Worker            << " res = " << operationValue0 << " " << getOperationName(m_op) << " " << operationValue1 << ";\n";
1935*35238bceSAndroid Build Coastguard Worker         break;
1936*35238bceSAndroid Build Coastguard Worker 
1937*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_UNARY_PREFIX_OPERATOR:
1938*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1939*35238bceSAndroid Build Coastguard Worker            << " res = " << getOperationName(m_op) << operationValue0 << ";\n";
1940*35238bceSAndroid Build Coastguard Worker         break;
1941*35238bceSAndroid Build Coastguard Worker 
1942*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_UNARY_POSTFIX_OPERATOR:
1943*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1944*35238bceSAndroid Build Coastguard Worker            << " res = " << operationValue0 << getOperationName(m_op) << ";\n";
1945*35238bceSAndroid Build Coastguard Worker         break;
1946*35238bceSAndroid Build Coastguard Worker 
1947*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_BINARY_FUNCTION:
1948*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1949*35238bceSAndroid Build Coastguard Worker            << " res = " << getOperationName(m_op) << "(" << operationValue0 << ", " << operationValue1 << ");\n";
1950*35238bceSAndroid Build Coastguard Worker         break;
1951*35238bceSAndroid Build Coastguard Worker 
1952*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_UNARY_FUNCTION:
1953*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1954*35238bceSAndroid Build Coastguard Worker            << " res = " << getOperationName(m_op) << "(" << operationValue0 << ");\n";
1955*35238bceSAndroid Build Coastguard Worker         break;
1956*35238bceSAndroid Build Coastguard Worker 
1957*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_ASSIGNMENT:
1958*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1959*35238bceSAndroid Build Coastguard Worker            << " res = " << operationValue0 << ";\n";
1960*35238bceSAndroid Build Coastguard Worker         op << "    res " << getOperationName(m_op) << " " << operationValue1 << ";\n";
1961*35238bceSAndroid Build Coastguard Worker         break;
1962*35238bceSAndroid Build Coastguard Worker 
1963*35238bceSAndroid Build Coastguard Worker     default:
1964*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1965*35238bceSAndroid Build Coastguard Worker     }
1966*35238bceSAndroid Build Coastguard Worker 
1967*35238bceSAndroid Build Coastguard Worker     // Reduction to vec3 (rgb). Check the used value too if it was modified
1968*35238bceSAndroid Build Coastguard Worker     op << "    " << (m_isVertexCase ? "v_color" : "dEQP_FragColor") << " = ";
1969*35238bceSAndroid Build Coastguard Worker 
1970*35238bceSAndroid Build Coastguard Worker     if (isOperationValueModifying(m_op))
1971*35238bceSAndroid Build Coastguard Worker         op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0) + vec4("
1972*35238bceSAndroid Build Coastguard Worker            << genGLSLMatToVec3Reduction(resultType, "tmpValue") << ", 0.0);\n";
1973*35238bceSAndroid Build Coastguard Worker     else
1974*35238bceSAndroid Build Coastguard Worker         op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0);\n";
1975*35238bceSAndroid Build Coastguard Worker 
1976*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
1977*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
1978*35238bceSAndroid Build Coastguard Worker 
1979*35238bceSAndroid Build Coastguard Worker     m_vertShaderSource = vtx.str();
1980*35238bceSAndroid Build Coastguard Worker     m_fragShaderSource = frag.str();
1981*35238bceSAndroid Build Coastguard Worker 
1982*35238bceSAndroid Build Coastguard Worker     // \todo [2012-02-14 pyry] Compute better values for matrix tests.
1983*35238bceSAndroid Build Coastguard Worker     m_userAttribTransforms.resize(4);
1984*35238bceSAndroid Build Coastguard Worker     for (int attribNdx = 0; attribNdx < 4; attribNdx++)
1985*35238bceSAndroid Build Coastguard Worker     {
1986*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx] = Mat4(0.0f);
1987*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx](0, 3) =
1988*35238bceSAndroid Build Coastguard Worker             0.1f + 0.1f * float(attribNdx); // !< prevent matrix*vec from going into zero (assuming vec.w != 0)
1989*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx](1, 3)                   = 0.2f + 0.1f * float(attribNdx); // !<
1990*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx](2, 3)                   = 0.3f + 0.1f * float(attribNdx); // !<
1991*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx](3, 3)                   = 0.4f + 0.1f * float(attribNdx); // !<
1992*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((0 + attribNdx) % 4, 0) = 1.0f;
1993*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((1 + attribNdx) % 4, 1) = 1.0f;
1994*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((2 + attribNdx) % 4, 2) = 1.0f;
1995*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((3 + attribNdx) % 4, 3) = 1.0f;
1996*35238bceSAndroid Build Coastguard Worker     }
1997*35238bceSAndroid Build Coastguard Worker 
1998*35238bceSAndroid Build Coastguard Worker     // prevent bad reference cases such as black result images by fine-tuning used matrices
1999*35238bceSAndroid Build Coastguard Worker     if (getOperationTestMatrixType(m_op) != TESTMATRIXTYPE_DEFAULT)
2000*35238bceSAndroid Build Coastguard Worker     {
2001*35238bceSAndroid Build Coastguard Worker         for (int attribNdx = 0; attribNdx < 4; attribNdx++)
2002*35238bceSAndroid Build Coastguard Worker         {
2003*35238bceSAndroid Build Coastguard Worker             for (int row = 0; row < 4; row++)
2004*35238bceSAndroid Build Coastguard Worker                 for (int col = 0; col < 4; col++)
2005*35238bceSAndroid Build Coastguard Worker                 {
2006*35238bceSAndroid Build Coastguard Worker                     switch (getOperationTestMatrixType(m_op))
2007*35238bceSAndroid Build Coastguard Worker                     {
2008*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_NEGATED:
2009*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col);
2010*35238bceSAndroid Build Coastguard Worker                         break;
2011*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_INCREMENTED:
2012*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) += 0.3f;
2013*35238bceSAndroid Build Coastguard Worker                         break;
2014*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_DECREMENTED:
2015*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) -= 0.3f;
2016*35238bceSAndroid Build Coastguard Worker                         break;
2017*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_NEGATED_INCREMENTED:
2018*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) =
2019*35238bceSAndroid Build Coastguard Worker                             -m_userAttribTransforms[attribNdx](row, col) + 0.3f;
2020*35238bceSAndroid Build Coastguard Worker                         break;
2021*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_INCREMENTED_LESS:
2022*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) -= 0.1f;
2023*35238bceSAndroid Build Coastguard Worker                         break;
2024*35238bceSAndroid Build Coastguard Worker 
2025*35238bceSAndroid Build Coastguard Worker                     default:
2026*35238bceSAndroid Build Coastguard Worker                         DE_ASSERT(false);
2027*35238bceSAndroid Build Coastguard Worker                         break;
2028*35238bceSAndroid Build Coastguard Worker                     }
2029*35238bceSAndroid Build Coastguard Worker                 }
2030*35238bceSAndroid Build Coastguard Worker         }
2031*35238bceSAndroid Build Coastguard Worker     }
2032*35238bceSAndroid Build Coastguard Worker     // The verification code doesn't deal with reduced precision, so we must quantize the data
2033*35238bceSAndroid Build Coastguard Worker     // here to try to avoid verification errors. No implementation seems to use lowp, so reduce
2034*35238bceSAndroid Build Coastguard Worker     // to mediump.
2035*35238bceSAndroid Build Coastguard Worker     if (resultPrec != PRECISION_HIGHP)
2036*35238bceSAndroid Build Coastguard Worker     {
2037*35238bceSAndroid Build Coastguard Worker         for (int attribNdx = 0; attribNdx < 4; attribNdx++)
2038*35238bceSAndroid Build Coastguard Worker         {
2039*35238bceSAndroid Build Coastguard Worker             for (int row = 0; row < 4; row++)
2040*35238bceSAndroid Build Coastguard Worker                 for (int col = 0; col < 4; col++)
2041*35238bceSAndroid Build Coastguard Worker                 {
2042*35238bceSAndroid Build Coastguard Worker                     m_userAttribTransforms[attribNdx](row, col) =
2043*35238bceSAndroid Build Coastguard Worker                         deFloat16To32(deFloat32To16(m_userAttribTransforms[attribNdx](row, col)));
2044*35238bceSAndroid Build Coastguard Worker                 }
2045*35238bceSAndroid Build Coastguard Worker         }
2046*35238bceSAndroid Build Coastguard Worker     }
2047*35238bceSAndroid Build Coastguard Worker 
2048*35238bceSAndroid Build Coastguard Worker     ShaderRenderCase::init();
2049*35238bceSAndroid Build Coastguard Worker 
2050*35238bceSAndroid Build Coastguard Worker     // reassign grid size prevent matrix inverse inf value.
2051*35238bceSAndroid Build Coastguard Worker     m_gridSize = 64;
2052*35238bceSAndroid Build Coastguard Worker }
2053*35238bceSAndroid Build Coastguard Worker 
genGLSLMatToVec3Reduction(const glu::DataType & matType,const char * varName)2054*35238bceSAndroid Build Coastguard Worker std::string ShaderMatrixCase::genGLSLMatToVec3Reduction(const glu::DataType &matType, const char *varName)
2055*35238bceSAndroid Build Coastguard Worker {
2056*35238bceSAndroid Build Coastguard Worker     std::ostringstream op;
2057*35238bceSAndroid Build Coastguard Worker 
2058*35238bceSAndroid Build Coastguard Worker     switch (matType)
2059*35238bceSAndroid Build Coastguard Worker     {
2060*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT:
2061*35238bceSAndroid Build Coastguard Worker         op << varName << ", " << varName << ", " << varName << "";
2062*35238bceSAndroid Build Coastguard Worker         break;
2063*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC2:
2064*35238bceSAndroid Build Coastguard Worker         op << varName << ".x, " << varName << ".y, " << varName << ".x";
2065*35238bceSAndroid Build Coastguard Worker         break;
2066*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC3:
2067*35238bceSAndroid Build Coastguard Worker         op << varName << "";
2068*35238bceSAndroid Build Coastguard Worker         break;
2069*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC4:
2070*35238bceSAndroid Build Coastguard Worker         op << varName << ".x, " << varName << ".y, " << varName << ".z+" << varName << ".w";
2071*35238bceSAndroid Build Coastguard Worker         break;
2072*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT2:
2073*35238bceSAndroid Build Coastguard Worker         op << varName << "[0][0], " << varName << "[1][0], " << varName << "[0][1]+" << varName << "[1][1]";
2074*35238bceSAndroid Build Coastguard Worker         break;
2075*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT2X3:
2076*35238bceSAndroid Build Coastguard Worker         op << varName << "[0] + " << varName << "[1]";
2077*35238bceSAndroid Build Coastguard Worker         break;
2078*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT2X4:
2079*35238bceSAndroid Build Coastguard Worker         op << varName << "[0].xyz + " << varName << "[1].yzw";
2080*35238bceSAndroid Build Coastguard Worker         break;
2081*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT3X2:
2082*35238bceSAndroid Build Coastguard Worker         op << varName << "[0][0]+" << varName << "[0][1], " << varName << "[1][0]+" << varName << "[1][1], " << varName
2083*35238bceSAndroid Build Coastguard Worker            << "[2][0]+" << varName << "[2][1]";
2084*35238bceSAndroid Build Coastguard Worker         break;
2085*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT3:
2086*35238bceSAndroid Build Coastguard Worker         op << varName << "[0] + " << varName << "[1] + " << varName << "[2]";
2087*35238bceSAndroid Build Coastguard Worker         break;
2088*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT3X4:
2089*35238bceSAndroid Build Coastguard Worker         op << varName << "[0].xyz + " << varName << "[1].yzw + " << varName << "[2].zwx";
2090*35238bceSAndroid Build Coastguard Worker         break;
2091*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT4X2:
2092*35238bceSAndroid Build Coastguard Worker         op << varName << "[0][0]+" << varName << "[0][1]+" << varName << "[3][0], " << varName << "[1][0]+" << varName
2093*35238bceSAndroid Build Coastguard Worker            << "[1][1]+" << varName << "[3][1], " << varName << "[2][0]+" << varName << "[2][1]";
2094*35238bceSAndroid Build Coastguard Worker         break;
2095*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT4X3:
2096*35238bceSAndroid Build Coastguard Worker         op << varName << "[0] + " << varName << "[1] + " << varName << "[2] + " << varName << "[3]";
2097*35238bceSAndroid Build Coastguard Worker         break;
2098*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT4:
2099*35238bceSAndroid Build Coastguard Worker         op << varName << "[0].xyz+" << varName << "[1].yzw+" << varName << "[2].zwx+" << varName << "[3].wxy";
2100*35238bceSAndroid Build Coastguard Worker         break;
2101*35238bceSAndroid Build Coastguard Worker 
2102*35238bceSAndroid Build Coastguard Worker     default:
2103*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2104*35238bceSAndroid Build Coastguard Worker     }
2105*35238bceSAndroid Build Coastguard Worker 
2106*35238bceSAndroid Build Coastguard Worker     return op.str();
2107*35238bceSAndroid Build Coastguard Worker }
2108*35238bceSAndroid Build Coastguard Worker 
setupUniforms(int programID,const tcu::Vec4 & constCoords)2109*35238bceSAndroid Build Coastguard Worker void ShaderMatrixCase::setupUniforms(int programID, const tcu::Vec4 &constCoords)
2110*35238bceSAndroid Build Coastguard Worker {
2111*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
2112*35238bceSAndroid Build Coastguard Worker 
2113*35238bceSAndroid Build Coastguard Worker     DE_UNREF(constCoords);
2114*35238bceSAndroid Build Coastguard Worker 
2115*35238bceSAndroid Build Coastguard Worker     for (int inNdx = 0; inNdx < 2; inNdx++)
2116*35238bceSAndroid Build Coastguard Worker     {
2117*35238bceSAndroid Build Coastguard Worker         const ShaderInput &in = inNdx > 0 ? m_in1 : m_in0;
2118*35238bceSAndroid Build Coastguard Worker 
2119*35238bceSAndroid Build Coastguard Worker         if (in.inputType == INPUTTYPE_UNIFORM)
2120*35238bceSAndroid Build Coastguard Worker         {
2121*35238bceSAndroid Build Coastguard Worker             int loc = gl.getUniformLocation(programID, (string("u_in") + de::toString(inNdx)).c_str());
2122*35238bceSAndroid Build Coastguard Worker 
2123*35238bceSAndroid Build Coastguard Worker             if (loc < 0)
2124*35238bceSAndroid Build Coastguard Worker                 continue;
2125*35238bceSAndroid Build Coastguard Worker 
2126*35238bceSAndroid Build Coastguard Worker             switch (in.dataType)
2127*35238bceSAndroid Build Coastguard Worker             {
2128*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT:
2129*35238bceSAndroid Build Coastguard Worker                 gl.uniform1f(loc, s_constInFloat[inNdx]);
2130*35238bceSAndroid Build Coastguard Worker                 break;
2131*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC2:
2132*35238bceSAndroid Build Coastguard Worker                 gl.uniform2fv(loc, 1, s_constInVec2[inNdx].getPtr());
2133*35238bceSAndroid Build Coastguard Worker                 break;
2134*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC3:
2135*35238bceSAndroid Build Coastguard Worker                 gl.uniform3fv(loc, 1, s_constInVec3[inNdx].getPtr());
2136*35238bceSAndroid Build Coastguard Worker                 break;
2137*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC4:
2138*35238bceSAndroid Build Coastguard Worker                 gl.uniform4fv(loc, 1, s_constInVec4[inNdx].getPtr());
2139*35238bceSAndroid Build Coastguard Worker                 break;
2140*35238bceSAndroid Build Coastguard Worker             // \note GLES3 supports transpose in matrix upload.
2141*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2:
2142*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix2fv(loc, 1, GL_TRUE, s_constInMat2x2[inNdx]);
2143*35238bceSAndroid Build Coastguard Worker                 break;
2144*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2X3:
2145*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix2x3fv(loc, 1, GL_TRUE, s_constInMat2x3[inNdx]);
2146*35238bceSAndroid Build Coastguard Worker                 break;
2147*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2X4:
2148*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix2x4fv(loc, 1, GL_TRUE, s_constInMat2x4[inNdx]);
2149*35238bceSAndroid Build Coastguard Worker                 break;
2150*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3X2:
2151*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix3x2fv(loc, 1, GL_TRUE, s_constInMat3x2[inNdx]);
2152*35238bceSAndroid Build Coastguard Worker                 break;
2153*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3:
2154*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix3fv(loc, 1, GL_TRUE, s_constInMat3x3[inNdx]);
2155*35238bceSAndroid Build Coastguard Worker                 break;
2156*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3X4:
2157*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix3x4fv(loc, 1, GL_TRUE, s_constInMat3x4[inNdx]);
2158*35238bceSAndroid Build Coastguard Worker                 break;
2159*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4X2:
2160*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix4x2fv(loc, 1, GL_TRUE, s_constInMat4x2[inNdx]);
2161*35238bceSAndroid Build Coastguard Worker                 break;
2162*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4X3:
2163*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix4x3fv(loc, 1, GL_TRUE, s_constInMat4x3[inNdx]);
2164*35238bceSAndroid Build Coastguard Worker                 break;
2165*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4:
2166*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix4fv(loc, 1, GL_TRUE, s_constInMat4x4[inNdx]);
2167*35238bceSAndroid Build Coastguard Worker                 break;
2168*35238bceSAndroid Build Coastguard Worker             default:
2169*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
2170*35238bceSAndroid Build Coastguard Worker             }
2171*35238bceSAndroid Build Coastguard Worker         }
2172*35238bceSAndroid Build Coastguard Worker     }
2173*35238bceSAndroid Build Coastguard Worker }
2174*35238bceSAndroid Build Coastguard Worker 
ShaderMatrixTests(Context & context)2175*35238bceSAndroid Build Coastguard Worker ShaderMatrixTests::ShaderMatrixTests(Context &context) : TestCaseGroup(context, "matrix", "Matrix Tests")
2176*35238bceSAndroid Build Coastguard Worker {
2177*35238bceSAndroid Build Coastguard Worker }
2178*35238bceSAndroid Build Coastguard Worker 
~ShaderMatrixTests(void)2179*35238bceSAndroid Build Coastguard Worker ShaderMatrixTests::~ShaderMatrixTests(void)
2180*35238bceSAndroid Build Coastguard Worker {
2181*35238bceSAndroid Build Coastguard Worker }
2182*35238bceSAndroid Build Coastguard Worker 
init(void)2183*35238bceSAndroid Build Coastguard Worker void ShaderMatrixTests::init(void)
2184*35238bceSAndroid Build Coastguard Worker {
2185*35238bceSAndroid Build Coastguard Worker     static const struct
2186*35238bceSAndroid Build Coastguard Worker     {
2187*35238bceSAndroid Build Coastguard Worker         const char *name;
2188*35238bceSAndroid Build Coastguard Worker         const char *desc;
2189*35238bceSAndroid Build Coastguard Worker         MatrixOp op;
2190*35238bceSAndroid Build Coastguard Worker         bool extendedInputTypeCases; // !< test with const and uniform types too
2191*35238bceSAndroid Build Coastguard Worker         bool createInputTypeGroup;   // !< create group for input types
2192*35238bceSAndroid Build Coastguard Worker     } ops[] = {
2193*35238bceSAndroid Build Coastguard Worker         {"add", "Matrix addition tests", OP_ADD, true, true},
2194*35238bceSAndroid Build Coastguard Worker         {"sub", "Matrix subtraction tests", OP_SUB, true, true},
2195*35238bceSAndroid Build Coastguard Worker         {"mul", "Matrix multiplication tests", OP_MUL, true, true},
2196*35238bceSAndroid Build Coastguard Worker         {"div", "Matrix division tests", OP_DIV, true, true},
2197*35238bceSAndroid Build Coastguard Worker         {"matrixcompmult", "Matrix component-wise multiplication tests", OP_COMP_MUL, false, true},
2198*35238bceSAndroid Build Coastguard Worker         {"outerproduct", "Matrix outerProduct() tests", OP_OUTER_PRODUCT, false, true},
2199*35238bceSAndroid Build Coastguard Worker         {"transpose", "Matrix transpose() tests", OP_TRANSPOSE, false, true},
2200*35238bceSAndroid Build Coastguard Worker         {"determinant", "Matrix determinant() tests", OP_DETERMINANT, false, true},
2201*35238bceSAndroid Build Coastguard Worker         {"inverse", "Matrix inverse() tests", OP_INVERSE, false, true},
2202*35238bceSAndroid Build Coastguard Worker         {"unary_addition", "Matrix unary addition tests", OP_UNARY_PLUS, false, false},
2203*35238bceSAndroid Build Coastguard Worker         {"negation", "Matrix negation tests", OP_NEGATION, false, false},
2204*35238bceSAndroid Build Coastguard Worker         {"pre_increment", "Matrix prefix increment tests", OP_PRE_INCREMENT, false, false},
2205*35238bceSAndroid Build Coastguard Worker         {"pre_decrement", "Matrix prefix decrement tests", OP_PRE_DECREMENT, false, false},
2206*35238bceSAndroid Build Coastguard Worker         {"post_increment", "Matrix postfix increment tests", OP_POST_INCREMENT, false, false},
2207*35238bceSAndroid Build Coastguard Worker         {"post_decrement", "Matrix postfix decrement tests", OP_POST_DECREMENT, false, false},
2208*35238bceSAndroid Build Coastguard Worker         {"add_assign", "Matrix add into tests", OP_ADD_INTO, false, false},
2209*35238bceSAndroid Build Coastguard Worker         {"sub_assign", "Matrix subtract from tests", OP_SUBTRACT_FROM, false, false},
2210*35238bceSAndroid Build Coastguard Worker         {"mul_assign", "Matrix multiply into tests", OP_MULTIPLY_INTO, false, false},
2211*35238bceSAndroid Build Coastguard Worker         {"div_assign", "Matrix divide into tests", OP_DIVIDE_INTO, false, false},
2212*35238bceSAndroid Build Coastguard Worker     };
2213*35238bceSAndroid Build Coastguard Worker 
2214*35238bceSAndroid Build Coastguard Worker     struct InputTypeSpec
2215*35238bceSAndroid Build Coastguard Worker     {
2216*35238bceSAndroid Build Coastguard Worker         const char *name;
2217*35238bceSAndroid Build Coastguard Worker         const char *desc;
2218*35238bceSAndroid Build Coastguard Worker         InputType type;
2219*35238bceSAndroid Build Coastguard Worker     };
2220*35238bceSAndroid Build Coastguard Worker     static const InputTypeSpec extendedInputTypes[] = {{"const", "Constant matrix input", INPUTTYPE_CONST},
2221*35238bceSAndroid Build Coastguard Worker                                                        {"uniform", "Uniform matrix input", INPUTTYPE_UNIFORM},
2222*35238bceSAndroid Build Coastguard Worker                                                        {"dynamic", "Dynamic matrix input", INPUTTYPE_DYNAMIC}};
2223*35238bceSAndroid Build Coastguard Worker     static const InputTypeSpec reducedInputTypes[]  = {{"dynamic", "Dynamic matrix input", INPUTTYPE_DYNAMIC}};
2224*35238bceSAndroid Build Coastguard Worker 
2225*35238bceSAndroid Build Coastguard Worker     static const DataType matrixTypes[] = {TYPE_FLOAT_MAT2,   TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT2X4,
2226*35238bceSAndroid Build Coastguard Worker                                            TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT3,   TYPE_FLOAT_MAT3X4,
2227*35238bceSAndroid Build Coastguard Worker                                            TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT4};
2228*35238bceSAndroid Build Coastguard Worker 
2229*35238bceSAndroid Build Coastguard Worker     static const Precision precisions[] = {PRECISION_LOWP, PRECISION_MEDIUMP, PRECISION_HIGHP};
2230*35238bceSAndroid Build Coastguard Worker 
2231*35238bceSAndroid Build Coastguard Worker     for (int opNdx = 0; opNdx < DE_LENGTH_OF_ARRAY(ops); opNdx++)
2232*35238bceSAndroid Build Coastguard Worker     {
2233*35238bceSAndroid Build Coastguard Worker         const InputTypeSpec *inTypeList =
2234*35238bceSAndroid Build Coastguard Worker             (ops[opNdx].extendedInputTypeCases) ? (extendedInputTypes) : (reducedInputTypes);
2235*35238bceSAndroid Build Coastguard Worker         const int inTypeListSize    = (ops[opNdx].extendedInputTypeCases) ? (DE_LENGTH_OF_ARRAY(extendedInputTypes)) :
2236*35238bceSAndroid Build Coastguard Worker                                                                             (DE_LENGTH_OF_ARRAY(reducedInputTypes));
2237*35238bceSAndroid Build Coastguard Worker         const MatrixOp op           = ops[opNdx].op;
2238*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *opGroup = new tcu::TestCaseGroup(m_testCtx, ops[opNdx].name, ops[opNdx].desc);
2239*35238bceSAndroid Build Coastguard Worker 
2240*35238bceSAndroid Build Coastguard Worker         addChild(opGroup);
2241*35238bceSAndroid Build Coastguard Worker 
2242*35238bceSAndroid Build Coastguard Worker         for (int inTypeNdx = 0; inTypeNdx < inTypeListSize; inTypeNdx++)
2243*35238bceSAndroid Build Coastguard Worker         {
2244*35238bceSAndroid Build Coastguard Worker             const InputType inputType = inTypeList[inTypeNdx].type;
2245*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *inGroup;
2246*35238bceSAndroid Build Coastguard Worker 
2247*35238bceSAndroid Build Coastguard Worker             if (ops[opNdx].createInputTypeGroup)
2248*35238bceSAndroid Build Coastguard Worker             {
2249*35238bceSAndroid Build Coastguard Worker                 inGroup = new tcu::TestCaseGroup(m_testCtx, inTypeList[inTypeNdx].name, inTypeList[inTypeNdx].desc);
2250*35238bceSAndroid Build Coastguard Worker                 opGroup->addChild(inGroup);
2251*35238bceSAndroid Build Coastguard Worker             }
2252*35238bceSAndroid Build Coastguard Worker             else
2253*35238bceSAndroid Build Coastguard Worker                 inGroup = opGroup;
2254*35238bceSAndroid Build Coastguard Worker 
2255*35238bceSAndroid Build Coastguard Worker             for (int matTypeNdx = 0; matTypeNdx < DE_LENGTH_OF_ARRAY(matrixTypes); matTypeNdx++)
2256*35238bceSAndroid Build Coastguard Worker             {
2257*35238bceSAndroid Build Coastguard Worker                 DataType matType        = matrixTypes[matTypeNdx];
2258*35238bceSAndroid Build Coastguard Worker                 int numCols             = getDataTypeMatrixNumColumns(matType);
2259*35238bceSAndroid Build Coastguard Worker                 int numRows             = getDataTypeMatrixNumRows(matType);
2260*35238bceSAndroid Build Coastguard Worker                 const char *matTypeName = getDataTypeName(matType);
2261*35238bceSAndroid Build Coastguard Worker 
2262*35238bceSAndroid Build Coastguard Worker                 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++)
2263*35238bceSAndroid Build Coastguard Worker                 {
2264*35238bceSAndroid Build Coastguard Worker                     Precision precision  = precisions[precNdx];
2265*35238bceSAndroid Build Coastguard Worker                     const char *precName = getPrecisionName(precision);
2266*35238bceSAndroid Build Coastguard Worker                     string baseName      = string(precName) + "_" + matTypeName + "_";
2267*35238bceSAndroid Build Coastguard Worker                     ShaderInput matIn(inputType, matType, precision);
2268*35238bceSAndroid Build Coastguard Worker 
2269*35238bceSAndroid Build Coastguard Worker                     if (isOperationMatrixScalar(op))
2270*35238bceSAndroid Build Coastguard Worker                     {
2271*35238bceSAndroid Build Coastguard Worker                         // Matrix-scalar \note For div cases we use uniform input.
2272*35238bceSAndroid Build Coastguard Worker                         ShaderInput scalarIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, TYPE_FLOAT,
2273*35238bceSAndroid Build Coastguard Worker                                              precision);
2274*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),
2275*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-scalar case", matIn, scalarIn, op, true));
2276*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),
2277*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-scalar case", matIn, scalarIn, op, false));
2278*35238bceSAndroid Build Coastguard Worker                     }
2279*35238bceSAndroid Build Coastguard Worker 
2280*35238bceSAndroid Build Coastguard Worker                     if (isOperationMatrixVector(op))
2281*35238bceSAndroid Build Coastguard Worker                     {
2282*35238bceSAndroid Build Coastguard Worker                         // Matrix-vector.
2283*35238bceSAndroid Build Coastguard Worker                         DataType colVecType = getDataTypeFloatVec(numCols);
2284*35238bceSAndroid Build Coastguard Worker                         ShaderInput colVecIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, colVecType,
2285*35238bceSAndroid Build Coastguard Worker                                              precision);
2286*35238bceSAndroid Build Coastguard Worker 
2287*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(
2288*35238bceSAndroid Build Coastguard Worker                             m_context, (baseName + getDataTypeName(colVecType) + "_vertex").c_str(),
2289*35238bceSAndroid Build Coastguard Worker                             "Matrix-vector case", matIn, colVecIn, op, true));
2290*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(
2291*35238bceSAndroid Build Coastguard Worker                             m_context, (baseName + getDataTypeName(colVecType) + "_fragment").c_str(),
2292*35238bceSAndroid Build Coastguard Worker                             "Matrix-vector case", matIn, colVecIn, op, false));
2293*35238bceSAndroid Build Coastguard Worker 
2294*35238bceSAndroid Build Coastguard Worker                         // Vector-matrix.
2295*35238bceSAndroid Build Coastguard Worker                         DataType rowVecType = getDataTypeFloatVec(numRows);
2296*35238bceSAndroid Build Coastguard Worker                         ShaderInput rowVecIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, rowVecType,
2297*35238bceSAndroid Build Coastguard Worker                                              precision);
2298*35238bceSAndroid Build Coastguard Worker                         string vecMatName = string(precName) + "_" + getDataTypeName(rowVecType) + "_" + matTypeName;
2299*35238bceSAndroid Build Coastguard Worker 
2300*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (vecMatName + "_vertex").c_str(),
2301*35238bceSAndroid Build Coastguard Worker                                                                "Vector-matrix case", rowVecIn, matIn, op, true));
2302*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (vecMatName + "_fragment").c_str(),
2303*35238bceSAndroid Build Coastguard Worker                                                                "Vector-matrix case", rowVecIn, matIn, op, false));
2304*35238bceSAndroid Build Coastguard Worker                     }
2305*35238bceSAndroid Build Coastguard Worker 
2306*35238bceSAndroid Build Coastguard Worker                     if (isOperationArithmeticMatrixMatrix(op))
2307*35238bceSAndroid Build Coastguard Worker                     {
2308*35238bceSAndroid Build Coastguard Worker                         // Arithmetic matrix-matrix multiplication.
2309*35238bceSAndroid Build Coastguard Worker                         for (int otherCols = 2; otherCols <= 4; otherCols++)
2310*35238bceSAndroid Build Coastguard Worker                         {
2311*35238bceSAndroid Build Coastguard Worker                             ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType,
2312*35238bceSAndroid Build Coastguard Worker                                                    getDataTypeMatrix(otherCols, numCols /* rows */), precision);
2313*35238bceSAndroid Build Coastguard Worker                             inGroup->addChild(new ShaderMatrixCase(
2314*35238bceSAndroid Build Coastguard Worker                                 m_context, (baseName + getDataTypeName(otherMatIn.dataType) + "_vertex").c_str(),
2315*35238bceSAndroid Build Coastguard Worker                                 "Matrix-matrix case", matIn, otherMatIn, op, true));
2316*35238bceSAndroid Build Coastguard Worker                             inGroup->addChild(new ShaderMatrixCase(
2317*35238bceSAndroid Build Coastguard Worker                                 m_context, (baseName + getDataTypeName(otherMatIn.dataType) + "_fragment").c_str(),
2318*35238bceSAndroid Build Coastguard Worker                                 "Matrix-matrix case", matIn, otherMatIn, op, false));
2319*35238bceSAndroid Build Coastguard Worker                         }
2320*35238bceSAndroid Build Coastguard Worker                     }
2321*35238bceSAndroid Build Coastguard Worker                     else if (isOperationComponentwiseMatrixMatrix(op))
2322*35238bceSAndroid Build Coastguard Worker                     {
2323*35238bceSAndroid Build Coastguard Worker                         // Component-wise.
2324*35238bceSAndroid Build Coastguard Worker                         ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType,
2325*35238bceSAndroid Build Coastguard Worker                                                precision);
2326*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + matTypeName + "_vertex").c_str(),
2327*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-matrix case", matIn, otherMatIn, op, true));
2328*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context,
2329*35238bceSAndroid Build Coastguard Worker                                                                (baseName + matTypeName + "_fragment").c_str(),
2330*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-matrix case", matIn, otherMatIn, op, false));
2331*35238bceSAndroid Build Coastguard Worker                     }
2332*35238bceSAndroid Build Coastguard Worker 
2333*35238bceSAndroid Build Coastguard Worker                     if (isOperationVectorVector(op))
2334*35238bceSAndroid Build Coastguard Worker                     {
2335*35238bceSAndroid Build Coastguard Worker                         ShaderInput vec1In(inputType, getDataTypeFloatVec(numRows), precision);
2336*35238bceSAndroid Build Coastguard Worker                         ShaderInput vec2In((inputType == INPUTTYPE_DYNAMIC) ? (INPUTTYPE_UNIFORM) : (inputType),
2337*35238bceSAndroid Build Coastguard Worker                                            getDataTypeFloatVec(numCols), precision);
2338*35238bceSAndroid Build Coastguard Worker 
2339*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),
2340*35238bceSAndroid Build Coastguard Worker                                                                "Vector-vector case", vec1In, vec2In, op, true));
2341*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),
2342*35238bceSAndroid Build Coastguard Worker                                                                "Vector-vector case", vec1In, vec2In, op, false));
2343*35238bceSAndroid Build Coastguard Worker                     }
2344*35238bceSAndroid Build Coastguard Worker 
2345*35238bceSAndroid Build Coastguard Worker                     if ((isOperationUnaryAnyMatrix(op)) || (isOperationUnarySymmetricMatrix(op) && numCols == numRows))
2346*35238bceSAndroid Build Coastguard Worker                     {
2347*35238bceSAndroid Build Coastguard Worker                         ShaderInput voidInput(INPUTTYPE_LAST, TYPE_LAST, PRECISION_LAST);
2348*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),
2349*35238bceSAndroid Build Coastguard Worker                                                                "Matrix case", matIn, voidInput, op, true));
2350*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),
2351*35238bceSAndroid Build Coastguard Worker                                                                "Matrix case", matIn, voidInput, op, false));
2352*35238bceSAndroid Build Coastguard Worker                     }
2353*35238bceSAndroid Build Coastguard Worker 
2354*35238bceSAndroid Build Coastguard Worker                     if ((isOperationAssignmentAnyMatrix(op)) ||
2355*35238bceSAndroid Build Coastguard Worker                         (isOperationAssignmentSymmetricMatrix(op) && numCols == numRows))
2356*35238bceSAndroid Build Coastguard Worker                     {
2357*35238bceSAndroid Build Coastguard Worker                         ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType,
2358*35238bceSAndroid Build Coastguard Worker                                                precision);
2359*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),
2360*35238bceSAndroid Build Coastguard Worker                                                                "Matrix assignment case", matIn, otherMatIn, op, true));
2361*35238bceSAndroid Build Coastguard Worker                         inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),
2362*35238bceSAndroid Build Coastguard Worker                                                                "Matrix assignment case", matIn, otherMatIn, op, false));
2363*35238bceSAndroid Build Coastguard Worker                     }
2364*35238bceSAndroid Build Coastguard Worker                 }
2365*35238bceSAndroid Build Coastguard Worker             }
2366*35238bceSAndroid Build Coastguard Worker         }
2367*35238bceSAndroid Build Coastguard Worker     }
2368*35238bceSAndroid Build Coastguard Worker }
2369*35238bceSAndroid Build Coastguard Worker 
2370*35238bceSAndroid Build Coastguard Worker } // namespace Functional
2371*35238bceSAndroid Build Coastguard Worker } // namespace gles3
2372*35238bceSAndroid Build Coastguard Worker } // namespace deqp
2373*35238bceSAndroid Build Coastguard Worker 
2374*35238bceSAndroid Build Coastguard Worker #if defined(_MSC_VER) && _MSC_FULL_VER == 191125507
2375*35238bceSAndroid Build Coastguard Worker // Work around crbug.com/759402 which is a code-gen bug in VC++ 2017, version
2376*35238bceSAndroid Build Coastguard Worker // 15.3.2.
2377*35238bceSAndroid Build Coastguard Worker #pragma optimize("", off)
2378*35238bceSAndroid Build Coastguard Worker #endif
2379