xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fShaderMatrixTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 2.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  *  + matrix source
31*35238bceSAndroid Build Coastguard Worker  *    - constant (ctor)
32*35238bceSAndroid Build Coastguard Worker  *    - uniform
33*35238bceSAndroid Build Coastguard Worker  *    - vertex input
34*35238bceSAndroid Build Coastguard Worker  *    - fragment input
35*35238bceSAndroid Build Coastguard Worker  *  + other operand: always dynamic data?
36*35238bceSAndroid Build Coastguard Worker  *  + how to reduce to vec3?
37*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker #include "es2fShaderMatrixTests.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "glsShaderRenderCase.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "gluShaderUtil.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "tcuMatrix.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "tcuMatrixUtil.hpp"
45*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
46*35238bceSAndroid Build Coastguard Worker 
47*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
48*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker namespace deqp
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker namespace gles2
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker namespace Functional
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker using std::string;
58*35238bceSAndroid Build Coastguard Worker using std::vector;
59*35238bceSAndroid Build Coastguard Worker using namespace glu;
60*35238bceSAndroid Build Coastguard Worker using namespace deqp::gls;
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker using tcu::Mat2;
63*35238bceSAndroid Build Coastguard Worker using tcu::Mat3;
64*35238bceSAndroid Build Coastguard Worker using tcu::Mat4;
65*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
66*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
67*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker // Uniform / constant values for tests.
70*35238bceSAndroid Build Coastguard Worker // \note Input1 should not contain 0 components as it is used as divisor in div cases.
71*35238bceSAndroid Build Coastguard Worker // \todo [2012-02-14 pyry] Make these dynamic.
72*35238bceSAndroid Build Coastguard Worker static const float s_constInFloat[2] = {0.5f, -0.2f};
73*35238bceSAndroid Build Coastguard Worker static const Vec2 s_constInVec2[2]   = {Vec2(1.2f, 0.5f), Vec2(0.5f, 1.0f)};
74*35238bceSAndroid Build Coastguard Worker static const Vec3 s_constInVec3[2]   = {Vec3(1.1f, 0.1f, 0.5f), Vec3(-0.2f, 0.5f, 0.8f)};
75*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)};
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker static const float s_constInMat20[] = {0.6f, -1.0f, 0.7f, 0.4f};
78*35238bceSAndroid Build Coastguard Worker static const float s_constInMat21[] = {-0.5f, -0.4f, 0.7f, -0.8f};
79*35238bceSAndroid Build Coastguard Worker 
80*35238bceSAndroid Build Coastguard Worker static const float s_constInMat31[] = {1.2f, 0.1f, -0.1f, 0.1f, 0.9f, 0.2f, 0.2f, -0.1f, 0.7f};
81*35238bceSAndroid Build Coastguard Worker static const float s_constInMat41[] = {1.2f,  -0.2f, 0.4f,  0.1f, 0.1f, 0.8f, -0.1f, -0.2f,
82*35238bceSAndroid Build Coastguard Worker                                        -0.2f, 0.1f,  -1.1f, 0.3f, 0.1f, 0.2f, 0.3f,  0.9f};
83*35238bceSAndroid Build Coastguard Worker 
84*35238bceSAndroid Build Coastguard Worker static const Mat2 s_constInMat2[2] = {tcu::Mat2(s_constInMat20), tcu::Mat2(s_constInMat21)};
85*35238bceSAndroid Build Coastguard Worker static const Mat3 s_constInMat3[2] = {tcu::translationMatrix(tcu::Vec2(0.2f, -0.3f)), tcu::Mat3(s_constInMat31)};
86*35238bceSAndroid Build Coastguard Worker static const Mat4 s_constInMat4[2] = {tcu::translationMatrix(tcu::Vec3(0.2f, -0.3f, 0.15f)), tcu::Mat4(s_constInMat41)};
87*35238bceSAndroid Build Coastguard Worker 
88*35238bceSAndroid Build Coastguard Worker namespace MatrixCaseUtils
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker 
91*35238bceSAndroid Build Coastguard Worker enum InputType
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_CONST = 0,
94*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_UNIFORM,
95*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_DYNAMIC,
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker     INPUTTYPE_LAST
98*35238bceSAndroid Build Coastguard Worker };
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker struct ShaderInput
101*35238bceSAndroid Build Coastguard Worker {
ShaderInputdeqp::gles2::Functional::MatrixCaseUtils::ShaderInput102*35238bceSAndroid Build Coastguard Worker     ShaderInput(InputType inputType_, DataType dataType_, Precision precision_)
103*35238bceSAndroid Build Coastguard Worker         : inputType(inputType_)
104*35238bceSAndroid Build Coastguard Worker         , dataType(dataType_)
105*35238bceSAndroid Build Coastguard Worker         , precision(precision_)
106*35238bceSAndroid Build Coastguard Worker     {
107*35238bceSAndroid Build Coastguard Worker     }
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker     InputType inputType;
110*35238bceSAndroid Build Coastguard Worker     DataType dataType;
111*35238bceSAndroid Build Coastguard Worker     Precision precision;
112*35238bceSAndroid Build Coastguard Worker };
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker enum MatrixOp
115*35238bceSAndroid Build Coastguard Worker {
116*35238bceSAndroid Build Coastguard Worker     OP_ADD = 0,
117*35238bceSAndroid Build Coastguard Worker     OP_SUB,
118*35238bceSAndroid Build Coastguard Worker     OP_MUL,
119*35238bceSAndroid Build Coastguard Worker     OP_DIV,
120*35238bceSAndroid Build Coastguard Worker     OP_COMP_MUL,
121*35238bceSAndroid Build Coastguard Worker     OP_UNARY_PLUS,
122*35238bceSAndroid Build Coastguard Worker     OP_NEGATION,
123*35238bceSAndroid Build Coastguard Worker     OP_PRE_INCREMENT,
124*35238bceSAndroid Build Coastguard Worker     OP_PRE_DECREMENT,
125*35238bceSAndroid Build Coastguard Worker     OP_POST_INCREMENT,
126*35238bceSAndroid Build Coastguard Worker     OP_POST_DECREMENT,
127*35238bceSAndroid Build Coastguard Worker     OP_ADD_INTO,
128*35238bceSAndroid Build Coastguard Worker     OP_SUBTRACT_FROM,
129*35238bceSAndroid Build Coastguard Worker     OP_MULTIPLY_INTO,
130*35238bceSAndroid Build Coastguard Worker     OP_DIVIDE_INTO,
131*35238bceSAndroid Build Coastguard Worker 
132*35238bceSAndroid Build Coastguard Worker     OP_LAST
133*35238bceSAndroid Build Coastguard Worker };
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker // Type traits.
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker template <int DataT>
138*35238bceSAndroid Build Coastguard Worker struct TypeTraits;
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker #define DECLARE_TYPE_TRAIT(DATATYPE, TYPE) \
141*35238bceSAndroid Build Coastguard Worker     template <>                            \
142*35238bceSAndroid Build Coastguard Worker     struct TypeTraits<DATATYPE>            \
143*35238bceSAndroid Build Coastguard Worker     {                                      \
144*35238bceSAndroid Build Coastguard Worker         typedef TYPE Type;                 \
145*35238bceSAndroid Build Coastguard Worker     }
146*35238bceSAndroid Build Coastguard Worker 
147*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT, float);
148*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC2, tcu::Vec2);
149*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC3, tcu::Vec3);
150*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC4, tcu::Vec4);
151*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2, tcu::Mat2);
152*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3, tcu::Mat3);
153*35238bceSAndroid Build Coastguard Worker DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4, tcu::Mat4);
154*35238bceSAndroid Build Coastguard Worker 
155*35238bceSAndroid Build Coastguard Worker // Operation info
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker enum OperationType
158*35238bceSAndroid Build Coastguard Worker {
159*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_BINARY_OPERATOR = 0,
160*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_BINARY_FUNCTION,
161*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_UNARY_PREFIX_OPERATOR,
162*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_UNARY_POSTFIX_OPERATOR,
163*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_ASSIGNMENT,
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker     OPERATIONTYPE_LAST
166*35238bceSAndroid Build Coastguard Worker };
167*35238bceSAndroid Build Coastguard Worker 
getOperationName(MatrixOp op)168*35238bceSAndroid Build Coastguard Worker static const char *getOperationName(MatrixOp op)
169*35238bceSAndroid Build Coastguard Worker {
170*35238bceSAndroid Build Coastguard Worker     switch (op)
171*35238bceSAndroid Build Coastguard Worker     {
172*35238bceSAndroid Build Coastguard Worker     case OP_ADD:
173*35238bceSAndroid Build Coastguard Worker         return "+";
174*35238bceSAndroid Build Coastguard Worker     case OP_SUB:
175*35238bceSAndroid Build Coastguard Worker         return "-";
176*35238bceSAndroid Build Coastguard Worker     case OP_MUL:
177*35238bceSAndroid Build Coastguard Worker         return "*";
178*35238bceSAndroid Build Coastguard Worker     case OP_DIV:
179*35238bceSAndroid Build Coastguard Worker         return "/";
180*35238bceSAndroid Build Coastguard Worker     case OP_COMP_MUL:
181*35238bceSAndroid Build Coastguard Worker         return "matrixCompMult";
182*35238bceSAndroid Build Coastguard Worker     case OP_UNARY_PLUS:
183*35238bceSAndroid Build Coastguard Worker         return "+";
184*35238bceSAndroid Build Coastguard Worker     case OP_NEGATION:
185*35238bceSAndroid Build Coastguard Worker         return "-";
186*35238bceSAndroid Build Coastguard Worker     case OP_PRE_INCREMENT:
187*35238bceSAndroid Build Coastguard Worker         return "++";
188*35238bceSAndroid Build Coastguard Worker     case OP_PRE_DECREMENT:
189*35238bceSAndroid Build Coastguard Worker         return "--";
190*35238bceSAndroid Build Coastguard Worker     case OP_POST_INCREMENT:
191*35238bceSAndroid Build Coastguard Worker         return "++";
192*35238bceSAndroid Build Coastguard Worker     case OP_POST_DECREMENT:
193*35238bceSAndroid Build Coastguard Worker         return "--";
194*35238bceSAndroid Build Coastguard Worker     case OP_ADD_INTO:
195*35238bceSAndroid Build Coastguard Worker         return "+=";
196*35238bceSAndroid Build Coastguard Worker     case OP_SUBTRACT_FROM:
197*35238bceSAndroid Build Coastguard Worker         return "-=";
198*35238bceSAndroid Build Coastguard Worker     case OP_MULTIPLY_INTO:
199*35238bceSAndroid Build Coastguard Worker         return "*=";
200*35238bceSAndroid Build Coastguard Worker     case OP_DIVIDE_INTO:
201*35238bceSAndroid Build Coastguard Worker         return "/=";
202*35238bceSAndroid Build Coastguard Worker     default:
203*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
204*35238bceSAndroid Build Coastguard Worker         return "";
205*35238bceSAndroid Build Coastguard Worker     }
206*35238bceSAndroid Build Coastguard Worker }
207*35238bceSAndroid Build Coastguard Worker 
getOperationType(MatrixOp op)208*35238bceSAndroid Build Coastguard Worker static OperationType getOperationType(MatrixOp op)
209*35238bceSAndroid Build Coastguard Worker {
210*35238bceSAndroid Build Coastguard Worker     switch (op)
211*35238bceSAndroid Build Coastguard Worker     {
212*35238bceSAndroid Build Coastguard Worker     case OP_ADD:
213*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
214*35238bceSAndroid Build Coastguard Worker     case OP_SUB:
215*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
216*35238bceSAndroid Build Coastguard Worker     case OP_MUL:
217*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
218*35238bceSAndroid Build Coastguard Worker     case OP_DIV:
219*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_OPERATOR;
220*35238bceSAndroid Build Coastguard Worker     case OP_COMP_MUL:
221*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_BINARY_FUNCTION;
222*35238bceSAndroid Build Coastguard Worker     case OP_UNARY_PLUS:
223*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
224*35238bceSAndroid Build Coastguard Worker     case OP_NEGATION:
225*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
226*35238bceSAndroid Build Coastguard Worker     case OP_PRE_INCREMENT:
227*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
228*35238bceSAndroid Build Coastguard Worker     case OP_PRE_DECREMENT:
229*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
230*35238bceSAndroid Build Coastguard Worker     case OP_POST_INCREMENT:
231*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
232*35238bceSAndroid Build Coastguard Worker     case OP_POST_DECREMENT:
233*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
234*35238bceSAndroid Build Coastguard Worker     case OP_ADD_INTO:
235*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
236*35238bceSAndroid Build Coastguard Worker     case OP_SUBTRACT_FROM:
237*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
238*35238bceSAndroid Build Coastguard Worker     case OP_MULTIPLY_INTO:
239*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
240*35238bceSAndroid Build Coastguard Worker     case OP_DIVIDE_INTO:
241*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_ASSIGNMENT;
242*35238bceSAndroid Build Coastguard Worker     default:
243*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
244*35238bceSAndroid Build Coastguard Worker         return OPERATIONTYPE_LAST;
245*35238bceSAndroid Build Coastguard Worker     }
246*35238bceSAndroid Build Coastguard Worker }
247*35238bceSAndroid Build Coastguard Worker 
248*35238bceSAndroid Build Coastguard Worker enum TestMatrixType
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_DEFAULT = 0,
251*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_NEGATED,
252*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_INCREMENTED,
253*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_DECREMENTED,
254*35238bceSAndroid Build Coastguard Worker 
255*35238bceSAndroid Build Coastguard Worker     TESTMATRIXTYPE_LAST
256*35238bceSAndroid Build Coastguard Worker };
257*35238bceSAndroid Build Coastguard Worker 
getOperationTestMatrixType(MatrixOp op)258*35238bceSAndroid Build Coastguard Worker static TestMatrixType getOperationTestMatrixType(MatrixOp op)
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker     switch (op)
261*35238bceSAndroid Build Coastguard Worker     {
262*35238bceSAndroid Build Coastguard Worker     case OP_ADD:
263*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
264*35238bceSAndroid Build Coastguard Worker     case OP_SUB:
265*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
266*35238bceSAndroid Build Coastguard Worker     case OP_MUL:
267*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
268*35238bceSAndroid Build Coastguard Worker     case OP_DIV:
269*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
270*35238bceSAndroid Build Coastguard Worker     case OP_COMP_MUL:
271*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
272*35238bceSAndroid Build Coastguard Worker     case OP_UNARY_PLUS:
273*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
274*35238bceSAndroid Build Coastguard Worker     case OP_NEGATION:
275*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_NEGATED;
276*35238bceSAndroid Build Coastguard Worker     case OP_PRE_INCREMENT:
277*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_NEGATED;
278*35238bceSAndroid Build Coastguard Worker     case OP_PRE_DECREMENT:
279*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_INCREMENTED;
280*35238bceSAndroid Build Coastguard Worker     case OP_POST_INCREMENT:
281*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_NEGATED;
282*35238bceSAndroid Build Coastguard Worker     case OP_POST_DECREMENT:
283*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
284*35238bceSAndroid Build Coastguard Worker     case OP_ADD_INTO:
285*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DECREMENTED;
286*35238bceSAndroid Build Coastguard Worker     case OP_SUBTRACT_FROM:
287*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
288*35238bceSAndroid Build Coastguard Worker     case OP_MULTIPLY_INTO:
289*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
290*35238bceSAndroid Build Coastguard Worker     case OP_DIVIDE_INTO:
291*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_DEFAULT;
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker     default:
294*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
295*35238bceSAndroid Build Coastguard Worker         return TESTMATRIXTYPE_LAST;
296*35238bceSAndroid Build Coastguard Worker     }
297*35238bceSAndroid Build Coastguard Worker }
298*35238bceSAndroid Build Coastguard Worker 
isOperationBinary(MatrixOp op)299*35238bceSAndroid Build Coastguard Worker static bool isOperationBinary(MatrixOp op)
300*35238bceSAndroid Build Coastguard Worker {
301*35238bceSAndroid Build Coastguard Worker     return getOperationType(op) == OPERATIONTYPE_BINARY_OPERATOR ||
302*35238bceSAndroid Build Coastguard Worker            getOperationType(op) == OPERATIONTYPE_BINARY_FUNCTION || getOperationType(op) == OPERATIONTYPE_ASSIGNMENT;
303*35238bceSAndroid Build Coastguard Worker }
304*35238bceSAndroid Build Coastguard Worker 
isOperationMatrixScalar(MatrixOp op)305*35238bceSAndroid Build Coastguard Worker static bool isOperationMatrixScalar(MatrixOp op)
306*35238bceSAndroid Build Coastguard Worker {
307*35238bceSAndroid Build Coastguard Worker     return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV;
308*35238bceSAndroid Build Coastguard Worker }
309*35238bceSAndroid Build Coastguard Worker 
isOperationMatrixVector(MatrixOp op)310*35238bceSAndroid Build Coastguard Worker static bool isOperationMatrixVector(MatrixOp op)
311*35238bceSAndroid Build Coastguard Worker {
312*35238bceSAndroid Build Coastguard Worker     return op == OP_MUL;
313*35238bceSAndroid Build Coastguard Worker }
314*35238bceSAndroid Build Coastguard Worker 
isOperationMatrixMatrix(MatrixOp op)315*35238bceSAndroid Build Coastguard Worker static bool isOperationMatrixMatrix(MatrixOp op)
316*35238bceSAndroid Build Coastguard Worker {
317*35238bceSAndroid Build Coastguard Worker     return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV || op == OP_COMP_MUL;
318*35238bceSAndroid Build Coastguard Worker }
319*35238bceSAndroid Build Coastguard Worker 
isOperationUnary(MatrixOp op)320*35238bceSAndroid Build Coastguard Worker static bool isOperationUnary(MatrixOp op)
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker     return op == OP_UNARY_PLUS || op == OP_NEGATION || op == OP_PRE_INCREMENT || op == OP_PRE_DECREMENT ||
323*35238bceSAndroid Build Coastguard Worker            op == OP_POST_INCREMENT || op == OP_POST_DECREMENT;
324*35238bceSAndroid Build Coastguard Worker }
325*35238bceSAndroid Build Coastguard Worker 
isOperationValueModifying(MatrixOp op)326*35238bceSAndroid Build Coastguard Worker static bool isOperationValueModifying(MatrixOp op)
327*35238bceSAndroid Build Coastguard Worker {
328*35238bceSAndroid Build Coastguard Worker     return op == OP_PRE_INCREMENT || op == OP_PRE_DECREMENT || op == OP_POST_INCREMENT || op == OP_POST_DECREMENT;
329*35238bceSAndroid Build Coastguard Worker }
330*35238bceSAndroid Build Coastguard Worker 
isOperationAssignment(MatrixOp op)331*35238bceSAndroid Build Coastguard Worker static bool isOperationAssignment(MatrixOp op)
332*35238bceSAndroid Build Coastguard Worker {
333*35238bceSAndroid Build Coastguard Worker     return op == OP_ADD_INTO || op == OP_SUBTRACT_FROM || op == OP_MULTIPLY_INTO || op == OP_DIVIDE_INTO;
334*35238bceSAndroid Build Coastguard Worker }
335*35238bceSAndroid Build Coastguard Worker 
336*35238bceSAndroid Build Coastguard Worker // Operation nature
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker enum OperationNature
339*35238bceSAndroid Build Coastguard Worker {
340*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_PURE = 0,
341*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_MUTATING,
342*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_ASSIGNMENT,
343*35238bceSAndroid Build Coastguard Worker 
344*35238bceSAndroid Build Coastguard Worker     OPERATIONNATURE_LAST
345*35238bceSAndroid Build Coastguard Worker };
346*35238bceSAndroid Build Coastguard Worker 
getOperationNature(MatrixOp op)347*35238bceSAndroid Build Coastguard Worker static OperationNature getOperationNature(MatrixOp op)
348*35238bceSAndroid Build Coastguard Worker {
349*35238bceSAndroid Build Coastguard Worker     if (isOperationAssignment(op))
350*35238bceSAndroid Build Coastguard Worker         return OPERATIONNATURE_ASSIGNMENT;
351*35238bceSAndroid Build Coastguard Worker 
352*35238bceSAndroid Build Coastguard Worker     if (isOperationValueModifying(op))
353*35238bceSAndroid Build Coastguard Worker         return OPERATIONNATURE_MUTATING;
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker     return OPERATIONNATURE_PURE;
356*35238bceSAndroid Build Coastguard Worker }
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker // Input value loader.
359*35238bceSAndroid Build Coastguard Worker 
360*35238bceSAndroid Build Coastguard Worker template <int InputT, int DataT>
361*35238bceSAndroid Build Coastguard Worker typename TypeTraits<DataT>::Type getInputValue(const ShaderEvalContext &evalCtx, int inputNdx);
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)364*35238bceSAndroid Build Coastguard Worker inline float getInputValue<INPUTTYPE_CONST, TYPE_FLOAT>(const ShaderEvalContext &evalCtx, int inputNdx)
365*35238bceSAndroid Build Coastguard Worker {
366*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
367*35238bceSAndroid Build Coastguard Worker     return s_constInFloat[inputNdx];
368*35238bceSAndroid Build Coastguard Worker }
369*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)370*35238bceSAndroid Build Coastguard Worker inline tcu::Vec2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC2>(const ShaderEvalContext &evalCtx, int inputNdx)
371*35238bceSAndroid Build Coastguard Worker {
372*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
373*35238bceSAndroid Build Coastguard Worker     return s_constInVec2[inputNdx];
374*35238bceSAndroid Build Coastguard Worker }
375*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)376*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC3>(const ShaderEvalContext &evalCtx, int inputNdx)
377*35238bceSAndroid Build Coastguard Worker {
378*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
379*35238bceSAndroid Build Coastguard Worker     return s_constInVec3[inputNdx];
380*35238bceSAndroid Build Coastguard Worker }
381*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)382*35238bceSAndroid Build Coastguard Worker inline tcu::Vec4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC4>(const ShaderEvalContext &evalCtx, int inputNdx)
383*35238bceSAndroid Build Coastguard Worker {
384*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
385*35238bceSAndroid Build Coastguard Worker     return s_constInVec4[inputNdx];
386*35238bceSAndroid Build Coastguard Worker }
387*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)388*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT2>(const ShaderEvalContext &evalCtx, int inputNdx)
389*35238bceSAndroid Build Coastguard Worker {
390*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
391*35238bceSAndroid Build Coastguard Worker     return s_constInMat2[inputNdx];
392*35238bceSAndroid Build Coastguard Worker }
393*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)394*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT3>(const ShaderEvalContext &evalCtx, int inputNdx)
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
397*35238bceSAndroid Build Coastguard Worker     return s_constInMat3[inputNdx];
398*35238bceSAndroid Build Coastguard Worker }
399*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)400*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT4>(const ShaderEvalContext &evalCtx, int inputNdx)
401*35238bceSAndroid Build Coastguard Worker {
402*35238bceSAndroid Build Coastguard Worker     DE_UNREF(evalCtx);
403*35238bceSAndroid Build Coastguard Worker     return s_constInMat4[inputNdx];
404*35238bceSAndroid Build Coastguard Worker }
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)407*35238bceSAndroid Build Coastguard Worker inline float getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT>(const ShaderEvalContext &evalCtx, int inputNdx)
408*35238bceSAndroid Build Coastguard Worker {
409*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
410*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.x();
411*35238bceSAndroid Build Coastguard Worker }
412*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)413*35238bceSAndroid Build Coastguard Worker inline tcu::Vec2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC2>(const ShaderEvalContext &evalCtx, int inputNdx)
414*35238bceSAndroid Build Coastguard Worker {
415*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
416*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.swizzle(0, 1);
417*35238bceSAndroid Build Coastguard Worker }
418*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)419*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC3>(const ShaderEvalContext &evalCtx, int inputNdx)
420*35238bceSAndroid Build Coastguard Worker {
421*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
422*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.swizzle(0, 1, 2);
423*35238bceSAndroid Build Coastguard Worker }
424*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)425*35238bceSAndroid Build Coastguard Worker inline tcu::Vec4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC4>(const ShaderEvalContext &evalCtx, int inputNdx)
426*35238bceSAndroid Build Coastguard Worker {
427*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx);
428*35238bceSAndroid Build Coastguard Worker     return evalCtx.coords.swizzle(0, 1, 2, 3);
429*35238bceSAndroid Build Coastguard Worker }
430*35238bceSAndroid Build Coastguard Worker 
431*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)432*35238bceSAndroid Build Coastguard Worker inline tcu::Mat2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2>(const ShaderEvalContext &evalCtx, int inputNdx)
433*35238bceSAndroid Build Coastguard Worker {
434*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
435*35238bceSAndroid Build Coastguard Worker     tcu::Mat2 m;
436*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1));
437*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1));
438*35238bceSAndroid Build Coastguard Worker     return m;
439*35238bceSAndroid Build Coastguard Worker }
440*35238bceSAndroid Build Coastguard Worker 
441*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)442*35238bceSAndroid Build Coastguard Worker inline tcu::Mat3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3>(const ShaderEvalContext &evalCtx, int inputNdx)
443*35238bceSAndroid Build Coastguard Worker {
444*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
445*35238bceSAndroid Build Coastguard Worker     tcu::Mat3 m;
446*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0].swizzle(0, 1, 2));
447*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1].swizzle(0, 1, 2));
448*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2].swizzle(0, 1, 2));
449*35238bceSAndroid Build Coastguard Worker     return m;
450*35238bceSAndroid Build Coastguard Worker }
451*35238bceSAndroid Build Coastguard Worker 
452*35238bceSAndroid Build Coastguard Worker template <>
getInputValue(const ShaderEvalContext & evalCtx,int inputNdx)453*35238bceSAndroid Build Coastguard Worker inline tcu::Mat4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4>(const ShaderEvalContext &evalCtx, int inputNdx)
454*35238bceSAndroid Build Coastguard Worker {
455*35238bceSAndroid Build Coastguard Worker     DE_UNREF(inputNdx); // Not used.
456*35238bceSAndroid Build Coastguard Worker     tcu::Mat4 m;
457*35238bceSAndroid Build Coastguard Worker     m.setColumn(0, evalCtx.in[0]);
458*35238bceSAndroid Build Coastguard Worker     m.setColumn(1, evalCtx.in[1]);
459*35238bceSAndroid Build Coastguard Worker     m.setColumn(2, evalCtx.in[2]);
460*35238bceSAndroid Build Coastguard Worker     m.setColumn(3, evalCtx.in[3]);
461*35238bceSAndroid Build Coastguard Worker     return m;
462*35238bceSAndroid Build Coastguard Worker }
463*35238bceSAndroid Build Coastguard Worker 
464*35238bceSAndroid Build Coastguard Worker // Reduction from expression result to vec3.
465*35238bceSAndroid Build Coastguard Worker 
reduceToVec3(const tcu::Vec2 & value)466*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Vec2 &value)
467*35238bceSAndroid Build Coastguard Worker {
468*35238bceSAndroid Build Coastguard Worker     return value.swizzle(0, 1, 0);
469*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Vec3 & value)470*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Vec3 &value)
471*35238bceSAndroid Build Coastguard Worker {
472*35238bceSAndroid Build Coastguard Worker     return value;
473*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Vec4 & value)474*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Vec4 &value)
475*35238bceSAndroid Build Coastguard Worker {
476*35238bceSAndroid Build Coastguard Worker     return tcu::Vec3(value.x(), value.y(), value.z() + value.w());
477*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat2 & value)478*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat2 &value)
479*35238bceSAndroid Build Coastguard Worker {
480*35238bceSAndroid Build Coastguard Worker     return tcu::Vec3(value(0, 0), value(0, 1), value(1, 0) + value(1, 1));
481*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat3 & value)482*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat3 &value)
483*35238bceSAndroid Build Coastguard Worker {
484*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0) + value.getColumn(1) + value.getColumn(2);
485*35238bceSAndroid Build Coastguard Worker }
reduceToVec3(const tcu::Mat4 & value)486*35238bceSAndroid Build Coastguard Worker inline tcu::Vec3 reduceToVec3(const tcu::Mat4 &value)
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker     return value.getColumn(0).swizzle(0, 1, 2) + value.getColumn(1).swizzle(1, 2, 3) +
489*35238bceSAndroid Build Coastguard Worker            value.getColumn(2).swizzle(2, 3, 0) + value.getColumn(3).swizzle(3, 0, 1);
490*35238bceSAndroid Build Coastguard Worker }
491*35238bceSAndroid Build Coastguard Worker 
492*35238bceSAndroid Build Coastguard Worker // matrixCompMult
493*35238bceSAndroid Build Coastguard Worker 
494*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)495*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> matrixCompMult(const tcu::Matrix<T, Rows, Cols> &a, const tcu::Matrix<T, Rows, Cols> &b)
496*35238bceSAndroid Build Coastguard Worker {
497*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
498*35238bceSAndroid Build Coastguard Worker 
499*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
500*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
501*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = a(r, c) * b(r, c);
502*35238bceSAndroid Build Coastguard Worker 
503*35238bceSAndroid Build Coastguard Worker     return retVal;
504*35238bceSAndroid Build Coastguard Worker }
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker // negate
507*35238bceSAndroid Build Coastguard Worker 
508*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
negate(const tcu::Matrix<T,Rows,Cols> & mat)509*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> negate(const tcu::Matrix<T, Rows, Cols> &mat)
510*35238bceSAndroid Build Coastguard Worker {
511*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
512*35238bceSAndroid Build Coastguard Worker 
513*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
514*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
515*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = -mat(r, c);
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker     return retVal;
518*35238bceSAndroid Build Coastguard Worker }
519*35238bceSAndroid Build Coastguard Worker 
520*35238bceSAndroid Build Coastguard Worker // increment/decrement
521*35238bceSAndroid Build Coastguard Worker 
522*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
increment(const tcu::Matrix<T,Rows,Cols> & mat)523*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> increment(const tcu::Matrix<T, Rows, Cols> &mat)
524*35238bceSAndroid Build Coastguard Worker {
525*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
526*35238bceSAndroid Build Coastguard Worker 
527*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
528*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
529*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = mat(r, c) + 1.0f;
530*35238bceSAndroid Build Coastguard Worker 
531*35238bceSAndroid Build Coastguard Worker     return retVal;
532*35238bceSAndroid Build Coastguard Worker }
533*35238bceSAndroid Build Coastguard Worker 
534*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
decrement(const tcu::Matrix<T,Rows,Cols> & mat)535*35238bceSAndroid Build Coastguard Worker tcu::Matrix<T, Rows, Cols> decrement(const tcu::Matrix<T, Rows, Cols> &mat)
536*35238bceSAndroid Build Coastguard Worker {
537*35238bceSAndroid Build Coastguard Worker     tcu::Matrix<T, Rows, Cols> retVal;
538*35238bceSAndroid Build Coastguard Worker 
539*35238bceSAndroid Build Coastguard Worker     for (int r = 0; r < Rows; ++r)
540*35238bceSAndroid Build Coastguard Worker         for (int c = 0; c < Cols; ++c)
541*35238bceSAndroid Build Coastguard Worker             retVal(r, c) = mat(r, c) - 1.0f;
542*35238bceSAndroid Build Coastguard Worker 
543*35238bceSAndroid Build Coastguard Worker     return retVal;
544*35238bceSAndroid Build Coastguard Worker }
545*35238bceSAndroid Build Coastguard Worker 
546*35238bceSAndroid Build Coastguard Worker // Evaluator template.
547*35238bceSAndroid Build Coastguard Worker 
548*35238bceSAndroid Build Coastguard Worker template <int Op, int In0Type, int In0DataType, int In1Type, int In1DataType>
549*35238bceSAndroid Build Coastguard Worker struct Evaluator;
550*35238bceSAndroid Build Coastguard Worker 
551*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
552*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_ADD, In0Type, In0DataType, In1Type, In1DataType>
553*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator554*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
555*35238bceSAndroid Build Coastguard Worker     {
556*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) +
557*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
558*35238bceSAndroid Build Coastguard Worker     }
559*35238bceSAndroid Build Coastguard Worker };
560*35238bceSAndroid Build Coastguard Worker 
561*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
562*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_SUB, In0Type, In0DataType, In1Type, In1DataType>
563*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator564*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
565*35238bceSAndroid Build Coastguard Worker     {
566*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) -
567*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
568*35238bceSAndroid Build Coastguard Worker     }
569*35238bceSAndroid Build Coastguard Worker };
570*35238bceSAndroid Build Coastguard Worker 
571*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
572*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_MUL, In0Type, In0DataType, In1Type, In1DataType>
573*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator574*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
575*35238bceSAndroid Build Coastguard Worker     {
576*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) *
577*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
578*35238bceSAndroid Build Coastguard Worker     }
579*35238bceSAndroid Build Coastguard Worker };
580*35238bceSAndroid Build Coastguard Worker 
581*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
582*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_DIV, In0Type, In0DataType, In1Type, In1DataType>
583*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator584*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
585*35238bceSAndroid Build Coastguard Worker     {
586*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) /
587*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
588*35238bceSAndroid Build Coastguard Worker     }
589*35238bceSAndroid Build Coastguard Worker };
590*35238bceSAndroid Build Coastguard Worker 
591*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
592*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_COMP_MUL, In0Type, In0DataType, In1Type, In1DataType>
593*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator594*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
595*35238bceSAndroid Build Coastguard Worker     {
596*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(matrixCompMult(getInputValue<In0Type, In0DataType>(evalCtx, 0),
597*35238bceSAndroid Build Coastguard Worker                                                           getInputValue<In1Type, In1DataType>(evalCtx, 1)));
598*35238bceSAndroid Build Coastguard Worker     }
599*35238bceSAndroid Build Coastguard Worker };
600*35238bceSAndroid Build Coastguard Worker 
601*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
602*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_UNARY_PLUS, In0Type, In0DataType, In1Type, In1DataType>
603*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator604*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
605*35238bceSAndroid Build Coastguard Worker     {
606*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0));
607*35238bceSAndroid Build Coastguard Worker     }
608*35238bceSAndroid Build Coastguard Worker };
609*35238bceSAndroid Build Coastguard Worker 
610*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
611*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_NEGATION, In0Type, In0DataType, In1Type, In1DataType>
612*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator613*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
614*35238bceSAndroid Build Coastguard Worker     {
615*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(negate(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
616*35238bceSAndroid Build Coastguard Worker     }
617*35238bceSAndroid Build Coastguard Worker };
618*35238bceSAndroid Build Coastguard Worker 
619*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
620*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_PRE_INCREMENT, In0Type, In0DataType, In1Type, In1DataType>
621*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator622*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
623*35238bceSAndroid Build Coastguard Worker     {
624*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
625*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(increment(getInputValue<In0Type, In0DataType>(evalCtx, 0))) +
626*35238bceSAndroid Build Coastguard Worker                               reduceToVec3(increment(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
627*35238bceSAndroid Build Coastguard Worker     }
628*35238bceSAndroid Build Coastguard Worker };
629*35238bceSAndroid Build Coastguard Worker 
630*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
631*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_PRE_DECREMENT, In0Type, In0DataType, In1Type, In1DataType>
632*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator633*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
634*35238bceSAndroid Build Coastguard Worker     {
635*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
636*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(decrement(getInputValue<In0Type, In0DataType>(evalCtx, 0))) +
637*35238bceSAndroid Build Coastguard Worker                               reduceToVec3(decrement(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
638*35238bceSAndroid Build Coastguard Worker     }
639*35238bceSAndroid Build Coastguard Worker };
640*35238bceSAndroid Build Coastguard Worker 
641*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
642*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_POST_INCREMENT, In0Type, In0DataType, In1Type, In1DataType>
643*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator644*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
645*35238bceSAndroid Build Coastguard Worker     {
646*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
647*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0)) +
648*35238bceSAndroid Build Coastguard Worker                               reduceToVec3(increment(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
649*35238bceSAndroid Build Coastguard Worker     }
650*35238bceSAndroid Build Coastguard Worker };
651*35238bceSAndroid Build Coastguard Worker 
652*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
653*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_POST_DECREMENT, In0Type, In0DataType, In1Type, In1DataType>
654*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator655*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
656*35238bceSAndroid Build Coastguard Worker     {
657*35238bceSAndroid Build Coastguard Worker         // modifying reduction: sum modified value too
658*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0)) +
659*35238bceSAndroid Build Coastguard Worker                               reduceToVec3(decrement(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
660*35238bceSAndroid Build Coastguard Worker     }
661*35238bceSAndroid Build Coastguard Worker };
662*35238bceSAndroid Build Coastguard Worker 
663*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
664*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_ADD_INTO, In0Type, In0DataType, In1Type, In1DataType>
665*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator666*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
667*35238bceSAndroid Build Coastguard Worker     {
668*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) +
669*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
670*35238bceSAndroid Build Coastguard Worker     }
671*35238bceSAndroid Build Coastguard Worker };
672*35238bceSAndroid Build Coastguard Worker 
673*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
674*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_SUBTRACT_FROM, In0Type, In0DataType, In1Type, In1DataType>
675*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator676*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
677*35238bceSAndroid Build Coastguard Worker     {
678*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) -
679*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
680*35238bceSAndroid Build Coastguard Worker     }
681*35238bceSAndroid Build Coastguard Worker };
682*35238bceSAndroid Build Coastguard Worker 
683*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
684*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_MULTIPLY_INTO, In0Type, In0DataType, In1Type, In1DataType>
685*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator686*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
687*35238bceSAndroid Build Coastguard Worker     {
688*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) *
689*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
690*35238bceSAndroid Build Coastguard Worker     }
691*35238bceSAndroid Build Coastguard Worker };
692*35238bceSAndroid Build Coastguard Worker 
693*35238bceSAndroid Build Coastguard Worker template <int In0Type, int In0DataType, int In1Type, int In1DataType>
694*35238bceSAndroid Build Coastguard Worker struct Evaluator<OP_DIVIDE_INTO, In0Type, In0DataType, In1Type, In1DataType>
695*35238bceSAndroid Build Coastguard Worker {
evaluatedeqp::gles2::Functional::MatrixCaseUtils::Evaluator696*35238bceSAndroid Build Coastguard Worker     static void evaluate(ShaderEvalContext &evalCtx)
697*35238bceSAndroid Build Coastguard Worker     {
698*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) /
699*35238bceSAndroid Build Coastguard Worker                                            getInputValue<In1Type, In1DataType>(evalCtx, 1));
700*35238bceSAndroid Build Coastguard Worker     }
701*35238bceSAndroid Build Coastguard Worker };
702*35238bceSAndroid Build Coastguard Worker 
getEvalFunc(const ShaderInput & in0,const ShaderInput & in1,MatrixOp op)703*35238bceSAndroid Build Coastguard Worker ShaderEvalFunc getEvalFunc(const ShaderInput &in0, const ShaderInput &in1, MatrixOp op)
704*35238bceSAndroid Build Coastguard Worker {
705*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(TYPE_LAST <= (1 << 7));
706*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(OP_LAST <= (1 << 4));
707*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(INPUTTYPE_LAST <= (1 << 2));
708*35238bceSAndroid Build Coastguard Worker 
709*35238bceSAndroid Build Coastguard Worker #define PACK_EVAL_CASE(OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE) \
710*35238bceSAndroid Build Coastguard Worker     (((OP) << 18) | ((IN0TYPE) << 16) | ((IN0DATATYPE) << 9) | ((IN1TYPE) << 7) | (IN1DATATYPE))
711*35238bceSAndroid Build Coastguard Worker 
712*35238bceSAndroid Build Coastguard Worker #define MAKE_EVAL_CASE(OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)   \
713*35238bceSAndroid Build Coastguard Worker     case PACK_EVAL_CASE(OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE): \
714*35238bceSAndroid Build Coastguard Worker         return Evaluator<OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE>::evaluate
715*35238bceSAndroid Build Coastguard Worker 
716*35238bceSAndroid Build Coastguard Worker #define SCALAR_OPS(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)          \
717*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_ADD, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
718*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_SUB, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
719*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_MUL, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
720*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_DIV, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)
721*35238bceSAndroid Build Coastguard Worker 
722*35238bceSAndroid Build Coastguard Worker #define ALL_OPS(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)             \
723*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_ADD, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
724*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_SUB, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
725*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_MUL, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
726*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_DIV, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
727*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_COMP_MUL, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)
728*35238bceSAndroid Build Coastguard Worker 
729*35238bceSAndroid Build Coastguard Worker #define MUL_OP(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE) \
730*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_MUL, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker #define MAKE_MAT_SCALAR_VEC_CASES(OP, TYPE0, TYPE1)       \
733*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_CONST, TYPE0, INPUTTYPE_CONST, TYPE1);   \
734*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_DYNAMIC, TYPE0, INPUTTYPE_CONST, TYPE1); \
735*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_CONST, TYPE0, INPUTTYPE_DYNAMIC, TYPE1); \
736*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_DYNAMIC, TYPE0, INPUTTYPE_DYNAMIC, TYPE1)
737*35238bceSAndroid Build Coastguard Worker 
738*35238bceSAndroid Build Coastguard Worker #define MAKE_MAT_MAT_CASES(OP, MATTYPE)                     \
739*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_CONST, MATTYPE, INPUTTYPE_CONST, MATTYPE); \
740*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_DYNAMIC, MATTYPE, INPUTTYPE_CONST, MATTYPE)
741*35238bceSAndroid Build Coastguard Worker 
742*35238bceSAndroid Build Coastguard Worker #define UNARY_OP(IN0TYPE, IN0DATATYPE)                                                   \
743*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_UNARY_PLUS, IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);     \
744*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_NEGATION, IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);       \
745*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_PRE_INCREMENT, IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);  \
746*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_PRE_DECREMENT, IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);  \
747*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_POST_INCREMENT, IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST); \
748*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_POST_DECREMENT, IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST)
749*35238bceSAndroid Build Coastguard Worker 
750*35238bceSAndroid Build Coastguard Worker #define MAKE_UNARY_CASES(OP, MATTYPE) \
751*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_CONST, MATTYPE);     \
752*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_DYNAMIC, MATTYPE)
753*35238bceSAndroid Build Coastguard Worker 
754*35238bceSAndroid Build Coastguard Worker #define ASSIGN_OP(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)                     \
755*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_ADD_INTO, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);      \
756*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_SUBTRACT_FROM, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
757*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_MULTIPLY_INTO, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE); \
758*35238bceSAndroid Build Coastguard Worker     MAKE_EVAL_CASE(OP_DIVIDE_INTO, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)
759*35238bceSAndroid Build Coastguard Worker 
760*35238bceSAndroid Build Coastguard Worker #define MAKE_ASSIGNMENT_CASES(OP, MATTYPE)                    \
761*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_CONST, MATTYPE, INPUTTYPE_CONST, MATTYPE);   \
762*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_DYNAMIC, MATTYPE, INPUTTYPE_CONST, MATTYPE); \
763*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_CONST, MATTYPE, INPUTTYPE_DYNAMIC, MATTYPE); \
764*35238bceSAndroid Build Coastguard Worker     OP(INPUTTYPE_DYNAMIC, MATTYPE, INPUTTYPE_DYNAMIC, MATTYPE)
765*35238bceSAndroid Build Coastguard Worker 
766*35238bceSAndroid Build Coastguard Worker     // \note At the moment there is no difference between uniform and const inputs. This saves binary size.
767*35238bceSAndroid Build Coastguard Worker     InputType in0Type = in0.inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_DYNAMIC : INPUTTYPE_CONST;
768*35238bceSAndroid Build Coastguard Worker     InputType in1Type = in1.inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_DYNAMIC : INPUTTYPE_CONST;
769*35238bceSAndroid Build Coastguard Worker 
770*35238bceSAndroid Build Coastguard Worker     switch (PACK_EVAL_CASE(op, in0Type, in0.dataType, in1Type, in1.dataType))
771*35238bceSAndroid Build Coastguard Worker     {
772*35238bceSAndroid Build Coastguard Worker         // Matrix-scalar.
773*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(SCALAR_OPS, TYPE_FLOAT_MAT2, TYPE_FLOAT);
774*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(SCALAR_OPS, TYPE_FLOAT_MAT3, TYPE_FLOAT);
775*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(SCALAR_OPS, TYPE_FLOAT_MAT4, TYPE_FLOAT);
776*35238bceSAndroid Build Coastguard Worker 
777*35238bceSAndroid Build Coastguard Worker         // Matrix-vector.
778*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(MUL_OP, TYPE_FLOAT_MAT2, TYPE_FLOAT_VEC2);
779*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(MUL_OP, TYPE_FLOAT_MAT3, TYPE_FLOAT_VEC3);
780*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(MUL_OP, TYPE_FLOAT_MAT4, TYPE_FLOAT_VEC4);
781*35238bceSAndroid Build Coastguard Worker 
782*35238bceSAndroid Build Coastguard Worker         // Vector-matrix.
783*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(MUL_OP, TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT2);
784*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(MUL_OP, TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT3);
785*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_SCALAR_VEC_CASES(MUL_OP, TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT4);
786*35238bceSAndroid Build Coastguard Worker 
787*35238bceSAndroid Build Coastguard Worker         // Matrix-matrix.
788*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_MAT_CASES(ALL_OPS, TYPE_FLOAT_MAT2);
789*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_MAT_CASES(ALL_OPS, TYPE_FLOAT_MAT3);
790*35238bceSAndroid Build Coastguard Worker         MAKE_MAT_MAT_CASES(ALL_OPS, TYPE_FLOAT_MAT4);
791*35238bceSAndroid Build Coastguard Worker 
792*35238bceSAndroid Build Coastguard Worker         // Unary matrix
793*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_CASES(UNARY_OP, TYPE_FLOAT_MAT2);
794*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_CASES(UNARY_OP, TYPE_FLOAT_MAT3);
795*35238bceSAndroid Build Coastguard Worker         MAKE_UNARY_CASES(UNARY_OP, TYPE_FLOAT_MAT4);
796*35238bceSAndroid Build Coastguard Worker 
797*35238bceSAndroid Build Coastguard Worker         // Assignment matrix
798*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_CASES(ASSIGN_OP, TYPE_FLOAT_MAT2);
799*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_CASES(ASSIGN_OP, TYPE_FLOAT_MAT3);
800*35238bceSAndroid Build Coastguard Worker         MAKE_ASSIGNMENT_CASES(ASSIGN_OP, TYPE_FLOAT_MAT4);
801*35238bceSAndroid Build Coastguard Worker 
802*35238bceSAndroid Build Coastguard Worker     default:
803*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
804*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
805*35238bceSAndroid Build Coastguard Worker     }
806*35238bceSAndroid Build Coastguard Worker 
807*35238bceSAndroid Build Coastguard Worker #undef PACK_EVAL_CASE
808*35238bceSAndroid Build Coastguard Worker #undef MAKE_EVAL_CASE
809*35238bceSAndroid Build Coastguard Worker #undef MUL_OP
810*35238bceSAndroid Build Coastguard Worker #undef ALL_OPS
811*35238bceSAndroid Build Coastguard Worker #undef MAKE_MAT_SCALAR_VEC_CASES
812*35238bceSAndroid Build Coastguard Worker #undef MAKE_MAT_MAT_CASES
813*35238bceSAndroid Build Coastguard Worker }
814*35238bceSAndroid Build Coastguard Worker 
815*35238bceSAndroid Build Coastguard Worker // Shader source format utilities.
816*35238bceSAndroid Build Coastguard Worker 
817*35238bceSAndroid Build Coastguard Worker template <int Size>
writeVectorConstructor(std::ostream & str,const tcu::Vector<float,Size> & v)818*35238bceSAndroid Build Coastguard Worker void writeVectorConstructor(std::ostream &str, const tcu::Vector<float, Size> &v)
819*35238bceSAndroid Build Coastguard Worker {
820*35238bceSAndroid Build Coastguard Worker     str << "vec" << Size << "(";
821*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < Size; ndx++)
822*35238bceSAndroid Build Coastguard Worker     {
823*35238bceSAndroid Build Coastguard Worker         if (ndx != 0)
824*35238bceSAndroid Build Coastguard Worker             str << ", ";
825*35238bceSAndroid Build Coastguard Worker         str << de::floatToString(v[ndx], 1);
826*35238bceSAndroid Build Coastguard Worker     }
827*35238bceSAndroid Build Coastguard Worker     str << ")";
828*35238bceSAndroid Build Coastguard Worker }
829*35238bceSAndroid Build Coastguard Worker 
830*35238bceSAndroid Build Coastguard Worker template <int Cols, int Rows>
writeMatrixConstructor(std::ostream & str,const tcu::Matrix<float,Rows,Cols> & m)831*35238bceSAndroid Build Coastguard Worker void writeMatrixConstructor(std::ostream &str, const tcu::Matrix<float, Rows, Cols> &m)
832*35238bceSAndroid Build Coastguard Worker {
833*35238bceSAndroid Build Coastguard Worker     if (Rows == Cols)
834*35238bceSAndroid Build Coastguard Worker         str << "mat" << Cols;
835*35238bceSAndroid Build Coastguard Worker     else
836*35238bceSAndroid Build Coastguard Worker         str << "mat" << Cols << "x" << Rows;
837*35238bceSAndroid Build Coastguard Worker 
838*35238bceSAndroid Build Coastguard Worker     str << "(";
839*35238bceSAndroid Build Coastguard Worker     for (int colNdx = 0; colNdx < Cols; colNdx++)
840*35238bceSAndroid Build Coastguard Worker     {
841*35238bceSAndroid Build Coastguard Worker         for (int rowNdx = 0; rowNdx < Rows; rowNdx++)
842*35238bceSAndroid Build Coastguard Worker         {
843*35238bceSAndroid Build Coastguard Worker             if (rowNdx > 0 || colNdx > 0)
844*35238bceSAndroid Build Coastguard Worker                 str << ", ";
845*35238bceSAndroid Build Coastguard Worker             str << de::floatToString(m(rowNdx, colNdx), 1);
846*35238bceSAndroid Build Coastguard Worker         }
847*35238bceSAndroid Build Coastguard Worker     }
848*35238bceSAndroid Build Coastguard Worker     str << ")";
849*35238bceSAndroid Build Coastguard Worker }
850*35238bceSAndroid Build Coastguard Worker 
851*35238bceSAndroid Build Coastguard Worker } // namespace MatrixCaseUtils
852*35238bceSAndroid Build Coastguard Worker 
853*35238bceSAndroid Build Coastguard Worker using namespace MatrixCaseUtils;
854*35238bceSAndroid Build Coastguard Worker 
855*35238bceSAndroid Build Coastguard Worker class ShaderMatrixCase : public ShaderRenderCase
856*35238bceSAndroid Build Coastguard Worker {
857*35238bceSAndroid Build Coastguard Worker public:
858*35238bceSAndroid Build Coastguard Worker     ShaderMatrixCase(Context &context, const char *name, const char *desc, const ShaderInput &in0,
859*35238bceSAndroid Build Coastguard Worker                      const ShaderInput &in1, MatrixOp op, bool isVertexCase);
860*35238bceSAndroid Build Coastguard Worker     ~ShaderMatrixCase(void);
861*35238bceSAndroid Build Coastguard Worker 
862*35238bceSAndroid Build Coastguard Worker     void init(void);
863*35238bceSAndroid Build Coastguard Worker 
864*35238bceSAndroid Build Coastguard Worker protected:
865*35238bceSAndroid Build Coastguard Worker     std::string genGLSLMatToVec3Reduction(const glu::DataType &matType, const char *varName);
866*35238bceSAndroid Build Coastguard Worker     void setupUniforms(int programID, const tcu::Vec4 &constCoords);
867*35238bceSAndroid Build Coastguard Worker 
868*35238bceSAndroid Build Coastguard Worker private:
869*35238bceSAndroid Build Coastguard Worker     ShaderInput m_in0;
870*35238bceSAndroid Build Coastguard Worker     ShaderInput m_in1;
871*35238bceSAndroid Build Coastguard Worker     MatrixOp m_op;
872*35238bceSAndroid Build Coastguard Worker };
873*35238bceSAndroid Build Coastguard Worker 
ShaderMatrixCase(Context & context,const char * name,const char * desc,const ShaderInput & in0,const ShaderInput & in1,MatrixOp op,bool isVertexCase)874*35238bceSAndroid Build Coastguard Worker ShaderMatrixCase::ShaderMatrixCase(Context &context, const char *name, const char *desc, const ShaderInput &in0,
875*35238bceSAndroid Build Coastguard Worker                                    const ShaderInput &in1, MatrixOp op, bool isVertexCase)
876*35238bceSAndroid Build Coastguard Worker     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc,
877*35238bceSAndroid Build Coastguard Worker                        isVertexCase, getEvalFunc(in0, in1, op))
878*35238bceSAndroid Build Coastguard Worker     , m_in0(in0)
879*35238bceSAndroid Build Coastguard Worker     , m_in1(in1)
880*35238bceSAndroid Build Coastguard Worker     , m_op(op)
881*35238bceSAndroid Build Coastguard Worker {
882*35238bceSAndroid Build Coastguard Worker }
883*35238bceSAndroid Build Coastguard Worker 
~ShaderMatrixCase(void)884*35238bceSAndroid Build Coastguard Worker ShaderMatrixCase::~ShaderMatrixCase(void)
885*35238bceSAndroid Build Coastguard Worker {
886*35238bceSAndroid Build Coastguard Worker }
887*35238bceSAndroid Build Coastguard Worker 
init(void)888*35238bceSAndroid Build Coastguard Worker void ShaderMatrixCase::init(void)
889*35238bceSAndroid Build Coastguard Worker {
890*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
891*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
892*35238bceSAndroid Build Coastguard Worker     std::ostringstream &op = m_isVertexCase ? vtx : frag;
893*35238bceSAndroid Build Coastguard Worker 
894*35238bceSAndroid Build Coastguard Worker     bool isInDynMat0 = isDataTypeMatrix(m_in0.dataType) && m_in0.inputType == INPUTTYPE_DYNAMIC;
895*35238bceSAndroid Build Coastguard Worker     bool isInDynMat1 = isDataTypeMatrix(m_in1.dataType) && m_in1.inputType == INPUTTYPE_DYNAMIC;
896*35238bceSAndroid Build Coastguard Worker     string inValue0;
897*35238bceSAndroid Build Coastguard Worker     string inValue1;
898*35238bceSAndroid Build Coastguard Worker     DataType resultType  = TYPE_LAST;
899*35238bceSAndroid Build Coastguard Worker     Precision resultPrec = m_in0.precision;
900*35238bceSAndroid Build Coastguard Worker     vector<string> passVars;
901*35238bceSAndroid Build Coastguard Worker     int numInputs = (isOperationBinary(m_op)) ? (2) : (1);
902*35238bceSAndroid Build Coastguard Worker 
903*35238bceSAndroid Build Coastguard Worker     std::string operationValue0;
904*35238bceSAndroid Build Coastguard Worker     std::string operationValue1;
905*35238bceSAndroid Build Coastguard Worker 
906*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!isInDynMat0 || !isInDynMat1); // Only single dynamic matrix input is allowed.
907*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isInDynMat0 && isInDynMat1);
908*35238bceSAndroid Build Coastguard Worker 
909*35238bceSAndroid Build Coastguard Worker     // Compute result type.
910*35238bceSAndroid Build Coastguard Worker     if (isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
911*35238bceSAndroid Build Coastguard Worker     {
912*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_in0.dataType == m_in1.dataType);
913*35238bceSAndroid Build Coastguard Worker         resultType = m_in0.dataType;
914*35238bceSAndroid Build Coastguard Worker     }
915*35238bceSAndroid Build Coastguard Worker     else if (getOperationType(m_op) == OPERATIONTYPE_UNARY_PREFIX_OPERATOR ||
916*35238bceSAndroid Build Coastguard Worker              getOperationType(m_op) == OPERATIONTYPE_UNARY_POSTFIX_OPERATOR)
917*35238bceSAndroid Build Coastguard Worker     {
918*35238bceSAndroid Build Coastguard Worker         resultType = m_in0.dataType;
919*35238bceSAndroid Build Coastguard Worker     }
920*35238bceSAndroid Build Coastguard Worker     else
921*35238bceSAndroid Build Coastguard Worker     {
922*35238bceSAndroid Build Coastguard Worker         int matNdx          = isDataTypeMatrix(m_in0.dataType) ? 0 : 1;
923*35238bceSAndroid Build Coastguard Worker         DataType matrixType = matNdx == 0 ? m_in0.dataType : m_in1.dataType;
924*35238bceSAndroid Build Coastguard Worker         DataType otherType  = matNdx == 0 ? m_in1.dataType : m_in0.dataType;
925*35238bceSAndroid Build Coastguard Worker 
926*35238bceSAndroid Build Coastguard Worker         if (otherType == TYPE_FLOAT)
927*35238bceSAndroid Build Coastguard Worker             resultType = matrixType;
928*35238bceSAndroid Build Coastguard Worker         else
929*35238bceSAndroid Build Coastguard Worker         {
930*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(isDataTypeVector(otherType));
931*35238bceSAndroid Build Coastguard Worker             resultType = otherType;
932*35238bceSAndroid Build Coastguard Worker         }
933*35238bceSAndroid Build Coastguard Worker     }
934*35238bceSAndroid Build Coastguard Worker 
935*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_position;\n";
936*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
937*35238bceSAndroid Build Coastguard Worker     {
938*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_color;\n";
939*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_color;\n";
940*35238bceSAndroid Build Coastguard Worker     }
941*35238bceSAndroid Build Coastguard Worker 
942*35238bceSAndroid Build Coastguard Worker     // Input declarations.
943*35238bceSAndroid Build Coastguard Worker     for (int inNdx = 0; inNdx < numInputs; inNdx++)
944*35238bceSAndroid Build Coastguard Worker     {
945*35238bceSAndroid Build Coastguard Worker         const ShaderInput &in = inNdx > 0 ? m_in1 : m_in0;
946*35238bceSAndroid Build Coastguard Worker         const char *precName  = getPrecisionName(in.precision);
947*35238bceSAndroid Build Coastguard Worker         const char *typeName  = getDataTypeName(in.dataType);
948*35238bceSAndroid Build Coastguard Worker         string &inValue       = inNdx > 0 ? inValue1 : inValue0;
949*35238bceSAndroid Build Coastguard Worker 
950*35238bceSAndroid Build Coastguard Worker         if (in.inputType == INPUTTYPE_DYNAMIC)
951*35238bceSAndroid Build Coastguard Worker         {
952*35238bceSAndroid Build Coastguard Worker             vtx << "attribute " << precName << " " << typeName << " a_";
953*35238bceSAndroid Build Coastguard Worker 
954*35238bceSAndroid Build Coastguard Worker             if (isDataTypeMatrix(in.dataType))
955*35238bceSAndroid Build Coastguard Worker             {
956*35238bceSAndroid Build Coastguard Worker                 // a_matN, v_matN
957*35238bceSAndroid Build Coastguard Worker                 vtx << typeName << ";\n";
958*35238bceSAndroid Build Coastguard Worker                 if (!m_isVertexCase)
959*35238bceSAndroid Build Coastguard Worker                 {
960*35238bceSAndroid Build Coastguard Worker                     vtx << "varying " << precName << " " << typeName << " v_" << typeName << ";\n";
961*35238bceSAndroid Build Coastguard Worker                     frag << "varying " << precName << " " << typeName << " v_" << typeName << ";\n";
962*35238bceSAndroid Build Coastguard Worker                     passVars.push_back(typeName);
963*35238bceSAndroid Build Coastguard Worker                 }
964*35238bceSAndroid Build Coastguard Worker 
965*35238bceSAndroid Build Coastguard Worker                 inValue = string(m_isVertexCase ? "a_" : "v_") + getDataTypeName(in.dataType);
966*35238bceSAndroid Build Coastguard Worker             }
967*35238bceSAndroid Build Coastguard Worker             else
968*35238bceSAndroid Build Coastguard Worker             {
969*35238bceSAndroid Build Coastguard Worker                 // a_coords, v_coords
970*35238bceSAndroid Build Coastguard Worker                 vtx << "coords;\n";
971*35238bceSAndroid Build Coastguard Worker                 if (!m_isVertexCase)
972*35238bceSAndroid Build Coastguard Worker                 {
973*35238bceSAndroid Build Coastguard Worker                     vtx << "varying " << precName << " " << typeName << " v_coords;\n";
974*35238bceSAndroid Build Coastguard Worker                     frag << "varying " << precName << " " << typeName << " v_coords;\n";
975*35238bceSAndroid Build Coastguard Worker                     passVars.push_back("coords");
976*35238bceSAndroid Build Coastguard Worker                 }
977*35238bceSAndroid Build Coastguard Worker 
978*35238bceSAndroid Build Coastguard Worker                 inValue = m_isVertexCase ? "a_coords" : "v_coords";
979*35238bceSAndroid Build Coastguard Worker             }
980*35238bceSAndroid Build Coastguard Worker         }
981*35238bceSAndroid Build Coastguard Worker         else if (in.inputType == INPUTTYPE_UNIFORM)
982*35238bceSAndroid Build Coastguard Worker         {
983*35238bceSAndroid Build Coastguard Worker             op << "uniform " << precName << " " << typeName << " u_in" << inNdx << ";\n";
984*35238bceSAndroid Build Coastguard Worker             inValue = string("u_in") + de::toString(inNdx);
985*35238bceSAndroid Build Coastguard Worker         }
986*35238bceSAndroid Build Coastguard Worker         else if (in.inputType == INPUTTYPE_CONST)
987*35238bceSAndroid Build Coastguard Worker         {
988*35238bceSAndroid Build Coastguard Worker             op << "const " << precName << " " << typeName << " in" << inNdx << " = ";
989*35238bceSAndroid Build Coastguard Worker 
990*35238bceSAndroid Build Coastguard Worker             // Generate declaration.
991*35238bceSAndroid Build Coastguard Worker             switch (in.dataType)
992*35238bceSAndroid Build Coastguard Worker             {
993*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT:
994*35238bceSAndroid Build Coastguard Worker                 op << de::floatToString(s_constInFloat[inNdx], 1);
995*35238bceSAndroid Build Coastguard Worker                 break;
996*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC2:
997*35238bceSAndroid Build Coastguard Worker                 writeVectorConstructor<2>(op, s_constInVec2[inNdx]);
998*35238bceSAndroid Build Coastguard Worker                 break;
999*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC3:
1000*35238bceSAndroid Build Coastguard Worker                 writeVectorConstructor<3>(op, s_constInVec3[inNdx]);
1001*35238bceSAndroid Build Coastguard Worker                 break;
1002*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC4:
1003*35238bceSAndroid Build Coastguard Worker                 writeVectorConstructor<4>(op, s_constInVec4[inNdx]);
1004*35238bceSAndroid Build Coastguard Worker                 break;
1005*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2:
1006*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<2, 2>(op, Mat2(s_constInMat2[inNdx]));
1007*35238bceSAndroid Build Coastguard Worker                 break;
1008*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3:
1009*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<3, 3>(op, Mat3(s_constInMat3[inNdx]));
1010*35238bceSAndroid Build Coastguard Worker                 break;
1011*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4:
1012*35238bceSAndroid Build Coastguard Worker                 writeMatrixConstructor<4, 4>(op, Mat4(s_constInMat4[inNdx]));
1013*35238bceSAndroid Build Coastguard Worker                 break;
1014*35238bceSAndroid Build Coastguard Worker 
1015*35238bceSAndroid Build Coastguard Worker             default:
1016*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1017*35238bceSAndroid Build Coastguard Worker             }
1018*35238bceSAndroid Build Coastguard Worker 
1019*35238bceSAndroid Build Coastguard Worker             op << ";\n";
1020*35238bceSAndroid Build Coastguard Worker 
1021*35238bceSAndroid Build Coastguard Worker             inValue = string("in") + de::toString(inNdx);
1022*35238bceSAndroid Build Coastguard Worker         }
1023*35238bceSAndroid Build Coastguard Worker     }
1024*35238bceSAndroid Build Coastguard Worker 
1025*35238bceSAndroid Build Coastguard Worker     vtx << "\n"
1026*35238bceSAndroid Build Coastguard Worker         << "void main (void)\n"
1027*35238bceSAndroid Build Coastguard Worker         << "{\n"
1028*35238bceSAndroid Build Coastguard Worker         << "    gl_Position = a_position;\n";
1029*35238bceSAndroid Build Coastguard Worker     frag << "\n"
1030*35238bceSAndroid Build Coastguard Worker          << "void main (void)\n"
1031*35238bceSAndroid Build Coastguard Worker          << "{\n";
1032*35238bceSAndroid Build Coastguard Worker 
1033*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
1034*35238bceSAndroid Build Coastguard Worker     {
1035*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = v_color;\n";
1036*35238bceSAndroid Build Coastguard Worker     }
1037*35238bceSAndroid Build Coastguard Worker     else
1038*35238bceSAndroid Build Coastguard Worker     {
1039*35238bceSAndroid Build Coastguard Worker         for (vector<string>::const_iterator copyIter = passVars.begin(); copyIter != passVars.end(); copyIter++)
1040*35238bceSAndroid Build Coastguard Worker             vtx << "    v_" << *copyIter << " = "
1041*35238bceSAndroid Build Coastguard Worker                 << "a_" << *copyIter << ";\n";
1042*35238bceSAndroid Build Coastguard Worker     }
1043*35238bceSAndroid Build Coastguard Worker 
1044*35238bceSAndroid Build Coastguard Worker     // Operation.
1045*35238bceSAndroid Build Coastguard Worker 
1046*35238bceSAndroid Build Coastguard Worker     switch (getOperationNature(m_op))
1047*35238bceSAndroid Build Coastguard Worker     {
1048*35238bceSAndroid Build Coastguard Worker     case OPERATIONNATURE_PURE:
1049*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
1050*35238bceSAndroid Build Coastguard Worker 
1051*35238bceSAndroid Build Coastguard Worker         operationValue0 = inValue0;
1052*35238bceSAndroid Build Coastguard Worker         operationValue1 = inValue1;
1053*35238bceSAndroid Build Coastguard Worker         break;
1054*35238bceSAndroid Build Coastguard Worker 
1055*35238bceSAndroid Build Coastguard Worker     case OPERATIONNATURE_MUTATING:
1056*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
1057*35238bceSAndroid Build Coastguard Worker 
1058*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " tmpValue = " << inValue0
1059*35238bceSAndroid Build Coastguard Worker            << ";\n";
1060*35238bceSAndroid Build Coastguard Worker 
1061*35238bceSAndroid Build Coastguard Worker         operationValue0 = "tmpValue";
1062*35238bceSAndroid Build Coastguard Worker         operationValue1 = inValue1;
1063*35238bceSAndroid Build Coastguard Worker         break;
1064*35238bceSAndroid Build Coastguard Worker 
1065*35238bceSAndroid Build Coastguard Worker     case OPERATIONNATURE_ASSIGNMENT:
1066*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(getOperationType(m_op) == OPERATIONTYPE_ASSIGNMENT);
1067*35238bceSAndroid Build Coastguard Worker 
1068*35238bceSAndroid Build Coastguard Worker         operationValue0 = inValue0;
1069*35238bceSAndroid Build Coastguard Worker         operationValue1 = inValue1;
1070*35238bceSAndroid Build Coastguard Worker         break;
1071*35238bceSAndroid Build Coastguard Worker 
1072*35238bceSAndroid Build Coastguard Worker     default:
1073*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1074*35238bceSAndroid Build Coastguard Worker     }
1075*35238bceSAndroid Build Coastguard Worker 
1076*35238bceSAndroid Build Coastguard Worker     switch (getOperationType(m_op))
1077*35238bceSAndroid Build Coastguard Worker     {
1078*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_BINARY_OPERATOR:
1079*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1080*35238bceSAndroid Build Coastguard Worker            << " res = " << operationValue0 << " " << getOperationName(m_op) << " " << operationValue1 << ";\n";
1081*35238bceSAndroid Build Coastguard Worker         break;
1082*35238bceSAndroid Build Coastguard Worker 
1083*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_UNARY_PREFIX_OPERATOR:
1084*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1085*35238bceSAndroid Build Coastguard Worker            << " res = " << getOperationName(m_op) << operationValue0 << ";\n";
1086*35238bceSAndroid Build Coastguard Worker         break;
1087*35238bceSAndroid Build Coastguard Worker 
1088*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_UNARY_POSTFIX_OPERATOR:
1089*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1090*35238bceSAndroid Build Coastguard Worker            << " res = " << operationValue0 << getOperationName(m_op) << ";\n";
1091*35238bceSAndroid Build Coastguard Worker         break;
1092*35238bceSAndroid Build Coastguard Worker 
1093*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_BINARY_FUNCTION:
1094*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1095*35238bceSAndroid Build Coastguard Worker            << " res = " << getOperationName(m_op) << "(" << operationValue0 << ", " << operationValue1 << ");\n";
1096*35238bceSAndroid Build Coastguard Worker         break;
1097*35238bceSAndroid Build Coastguard Worker 
1098*35238bceSAndroid Build Coastguard Worker     case OPERATIONTYPE_ASSIGNMENT:
1099*35238bceSAndroid Build Coastguard Worker         op << "    " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType)
1100*35238bceSAndroid Build Coastguard Worker            << " res = " << operationValue0 << ";\n";
1101*35238bceSAndroid Build Coastguard Worker         op << "    res " << getOperationName(m_op) << " " << operationValue1 << ";\n";
1102*35238bceSAndroid Build Coastguard Worker         break;
1103*35238bceSAndroid Build Coastguard Worker 
1104*35238bceSAndroid Build Coastguard Worker     default:
1105*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1106*35238bceSAndroid Build Coastguard Worker     }
1107*35238bceSAndroid Build Coastguard Worker 
1108*35238bceSAndroid Build Coastguard Worker     // Reduction to vec3 (rgb). Check the used value too if it was modified.
1109*35238bceSAndroid Build Coastguard Worker     op << "    " << (m_isVertexCase ? "v_color" : "gl_FragColor") << " = ";
1110*35238bceSAndroid Build Coastguard Worker 
1111*35238bceSAndroid Build Coastguard Worker     if (isOperationValueModifying(m_op))
1112*35238bceSAndroid Build Coastguard Worker         op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0) + vec4("
1113*35238bceSAndroid Build Coastguard Worker            << genGLSLMatToVec3Reduction(resultType, "tmpValue") << ", 0.0);\n";
1114*35238bceSAndroid Build Coastguard Worker     else
1115*35238bceSAndroid Build Coastguard Worker         op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0);\n";
1116*35238bceSAndroid Build Coastguard Worker 
1117*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
1118*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
1119*35238bceSAndroid Build Coastguard Worker 
1120*35238bceSAndroid Build Coastguard Worker     m_vertShaderSource = vtx.str();
1121*35238bceSAndroid Build Coastguard Worker     m_fragShaderSource = frag.str();
1122*35238bceSAndroid Build Coastguard Worker 
1123*35238bceSAndroid Build Coastguard Worker     // \todo [2012-02-14 pyry] Compute better values for matrix tests.
1124*35238bceSAndroid Build Coastguard Worker     m_userAttribTransforms.resize(4);
1125*35238bceSAndroid Build Coastguard Worker     for (int attribNdx = 0; attribNdx < 4; attribNdx++)
1126*35238bceSAndroid Build Coastguard Worker     {
1127*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]                         = Mat4(0.0f);
1128*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((0 + attribNdx) % 4, 0) = 1.0f;
1129*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((1 + attribNdx) % 4, 1) = 1.0f;
1130*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((2 + attribNdx) % 4, 2) = 1.0f;
1131*35238bceSAndroid Build Coastguard Worker         m_userAttribTransforms[attribNdx]((3 + attribNdx) % 4, 3) = 1.0f;
1132*35238bceSAndroid Build Coastguard Worker     }
1133*35238bceSAndroid Build Coastguard Worker 
1134*35238bceSAndroid Build Coastguard Worker     // prevent bad reference cases such as black result images by fine-tuning used matrices
1135*35238bceSAndroid Build Coastguard Worker     if (getOperationTestMatrixType(m_op) != TESTMATRIXTYPE_DEFAULT)
1136*35238bceSAndroid Build Coastguard Worker     {
1137*35238bceSAndroid Build Coastguard Worker         for (int attribNdx = 0; attribNdx < 4; attribNdx++)
1138*35238bceSAndroid Build Coastguard Worker         {
1139*35238bceSAndroid Build Coastguard Worker             for (int row = 0; row < 4; row++)
1140*35238bceSAndroid Build Coastguard Worker                 for (int col = 0; col < 4; col++)
1141*35238bceSAndroid Build Coastguard Worker                 {
1142*35238bceSAndroid Build Coastguard Worker                     switch (getOperationTestMatrixType(m_op))
1143*35238bceSAndroid Build Coastguard Worker                     {
1144*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_NEGATED:
1145*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col);
1146*35238bceSAndroid Build Coastguard Worker                         break;
1147*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_INCREMENTED:
1148*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) += 0.3f;
1149*35238bceSAndroid Build Coastguard Worker                         break;
1150*35238bceSAndroid Build Coastguard Worker                     case TESTMATRIXTYPE_DECREMENTED:
1151*35238bceSAndroid Build Coastguard Worker                         m_userAttribTransforms[attribNdx](row, col) -= 0.1f;
1152*35238bceSAndroid Build Coastguard Worker                         break;
1153*35238bceSAndroid Build Coastguard Worker 
1154*35238bceSAndroid Build Coastguard Worker                     default:
1155*35238bceSAndroid Build Coastguard Worker                         DE_ASSERT(false);
1156*35238bceSAndroid Build Coastguard Worker                         break;
1157*35238bceSAndroid Build Coastguard Worker                     }
1158*35238bceSAndroid Build Coastguard Worker                 }
1159*35238bceSAndroid Build Coastguard Worker         }
1160*35238bceSAndroid Build Coastguard Worker     }
1161*35238bceSAndroid Build Coastguard Worker 
1162*35238bceSAndroid Build Coastguard Worker     ShaderRenderCase::init();
1163*35238bceSAndroid Build Coastguard Worker }
1164*35238bceSAndroid Build Coastguard Worker 
genGLSLMatToVec3Reduction(const glu::DataType & matType,const char * varName)1165*35238bceSAndroid Build Coastguard Worker std::string ShaderMatrixCase::genGLSLMatToVec3Reduction(const glu::DataType &matType, const char *varName)
1166*35238bceSAndroid Build Coastguard Worker {
1167*35238bceSAndroid Build Coastguard Worker     std::ostringstream op;
1168*35238bceSAndroid Build Coastguard Worker 
1169*35238bceSAndroid Build Coastguard Worker     switch (matType)
1170*35238bceSAndroid Build Coastguard Worker     {
1171*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT:
1172*35238bceSAndroid Build Coastguard Worker         op << varName << ", " << varName << ", " << varName << "";
1173*35238bceSAndroid Build Coastguard Worker         break;
1174*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC2:
1175*35238bceSAndroid Build Coastguard Worker         op << varName << ".x, " << varName << ".y, " << varName << ".x";
1176*35238bceSAndroid Build Coastguard Worker         break;
1177*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC3:
1178*35238bceSAndroid Build Coastguard Worker         op << varName << "";
1179*35238bceSAndroid Build Coastguard Worker         break;
1180*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC4:
1181*35238bceSAndroid Build Coastguard Worker         op << varName << ".x, " << varName << ".y, " << varName << ".z+" << varName << ".w";
1182*35238bceSAndroid Build Coastguard Worker         break;
1183*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT2:
1184*35238bceSAndroid Build Coastguard Worker         op << varName << "[0][0], " << varName << "[1][0], " << varName << "[0][1]+" << varName << "[1][1]";
1185*35238bceSAndroid Build Coastguard Worker         break;
1186*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT3:
1187*35238bceSAndroid Build Coastguard Worker         op << varName << "[0]+" << varName << "[1]+" << varName << "[2]";
1188*35238bceSAndroid Build Coastguard Worker         break;
1189*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT4:
1190*35238bceSAndroid Build Coastguard Worker         op << varName << "[0].xyz+" << varName << "[1].yzw+" << varName << "[2].zwx+" << varName << "[3].wxy";
1191*35238bceSAndroid Build Coastguard Worker         break;
1192*35238bceSAndroid Build Coastguard Worker 
1193*35238bceSAndroid Build Coastguard Worker     default:
1194*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1195*35238bceSAndroid Build Coastguard Worker     }
1196*35238bceSAndroid Build Coastguard Worker 
1197*35238bceSAndroid Build Coastguard Worker     return op.str();
1198*35238bceSAndroid Build Coastguard Worker }
1199*35238bceSAndroid Build Coastguard Worker 
setupUniforms(int programID,const tcu::Vec4 & constCoords)1200*35238bceSAndroid Build Coastguard Worker void ShaderMatrixCase::setupUniforms(int programID, const tcu::Vec4 &constCoords)
1201*35238bceSAndroid Build Coastguard Worker {
1202*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
1203*35238bceSAndroid Build Coastguard Worker 
1204*35238bceSAndroid Build Coastguard Worker     DE_UNREF(constCoords);
1205*35238bceSAndroid Build Coastguard Worker 
1206*35238bceSAndroid Build Coastguard Worker     for (int inNdx = 0; inNdx < 2; inNdx++)
1207*35238bceSAndroid Build Coastguard Worker     {
1208*35238bceSAndroid Build Coastguard Worker         const ShaderInput &in = inNdx > 0 ? m_in1 : m_in0;
1209*35238bceSAndroid Build Coastguard Worker 
1210*35238bceSAndroid Build Coastguard Worker         if (in.inputType == INPUTTYPE_UNIFORM)
1211*35238bceSAndroid Build Coastguard Worker         {
1212*35238bceSAndroid Build Coastguard Worker             int loc = gl.getUniformLocation(programID, (string("u_in") + de::toString(inNdx)).c_str());
1213*35238bceSAndroid Build Coastguard Worker 
1214*35238bceSAndroid Build Coastguard Worker             if (loc < 0)
1215*35238bceSAndroid Build Coastguard Worker                 continue;
1216*35238bceSAndroid Build Coastguard Worker 
1217*35238bceSAndroid Build Coastguard Worker             switch (in.dataType)
1218*35238bceSAndroid Build Coastguard Worker             {
1219*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT:
1220*35238bceSAndroid Build Coastguard Worker                 gl.uniform1f(loc, s_constInFloat[inNdx]);
1221*35238bceSAndroid Build Coastguard Worker                 break;
1222*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC2:
1223*35238bceSAndroid Build Coastguard Worker                 gl.uniform2fv(loc, 1, s_constInVec2[inNdx].getPtr());
1224*35238bceSAndroid Build Coastguard Worker                 break;
1225*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC3:
1226*35238bceSAndroid Build Coastguard Worker                 gl.uniform3fv(loc, 1, s_constInVec3[inNdx].getPtr());
1227*35238bceSAndroid Build Coastguard Worker                 break;
1228*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_VEC4:
1229*35238bceSAndroid Build Coastguard Worker                 gl.uniform4fv(loc, 1, s_constInVec4[inNdx].getPtr());
1230*35238bceSAndroid Build Coastguard Worker                 break;
1231*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT2:
1232*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix2fv(loc, 1, GL_FALSE, s_constInMat2[inNdx].getColumnMajorData().getPtr());
1233*35238bceSAndroid Build Coastguard Worker                 break;
1234*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT3:
1235*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix3fv(loc, 1, GL_FALSE, s_constInMat3[inNdx].getColumnMajorData().getPtr());
1236*35238bceSAndroid Build Coastguard Worker                 break;
1237*35238bceSAndroid Build Coastguard Worker             case TYPE_FLOAT_MAT4:
1238*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix4fv(loc, 1, GL_FALSE, s_constInMat4[inNdx].getColumnMajorData().getPtr());
1239*35238bceSAndroid Build Coastguard Worker                 break;
1240*35238bceSAndroid Build Coastguard Worker             default:
1241*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1242*35238bceSAndroid Build Coastguard Worker             }
1243*35238bceSAndroid Build Coastguard Worker         }
1244*35238bceSAndroid Build Coastguard Worker     }
1245*35238bceSAndroid Build Coastguard Worker }
1246*35238bceSAndroid Build Coastguard Worker 
ShaderMatrixTests(Context & context)1247*35238bceSAndroid Build Coastguard Worker ShaderMatrixTests::ShaderMatrixTests(Context &context) : TestCaseGroup(context, "matrix", "Matrix Tests")
1248*35238bceSAndroid Build Coastguard Worker {
1249*35238bceSAndroid Build Coastguard Worker }
1250*35238bceSAndroid Build Coastguard Worker 
~ShaderMatrixTests(void)1251*35238bceSAndroid Build Coastguard Worker ShaderMatrixTests::~ShaderMatrixTests(void)
1252*35238bceSAndroid Build Coastguard Worker {
1253*35238bceSAndroid Build Coastguard Worker }
1254*35238bceSAndroid Build Coastguard Worker 
init(void)1255*35238bceSAndroid Build Coastguard Worker void ShaderMatrixTests::init(void)
1256*35238bceSAndroid Build Coastguard Worker {
1257*35238bceSAndroid Build Coastguard Worker     static const struct
1258*35238bceSAndroid Build Coastguard Worker     {
1259*35238bceSAndroid Build Coastguard Worker         const char *name;
1260*35238bceSAndroid Build Coastguard Worker         const char *desc;
1261*35238bceSAndroid Build Coastguard Worker         MatrixOp op;
1262*35238bceSAndroid Build Coastguard Worker         bool extendedInputTypeCases; // !< test with const and uniform types too
1263*35238bceSAndroid Build Coastguard Worker     } ops[] = {
1264*35238bceSAndroid Build Coastguard Worker         {"add", "Matrix addition tests", OP_ADD, true},
1265*35238bceSAndroid Build Coastguard Worker         {"sub", "Matrix subtraction tests", OP_SUB, true},
1266*35238bceSAndroid Build Coastguard Worker         {"mul", "Matrix multiplication tests", OP_MUL, true},
1267*35238bceSAndroid Build Coastguard Worker         {"div", "Matrix division tests", OP_DIV, true},
1268*35238bceSAndroid Build Coastguard Worker         {"matrixcompmult", "Matrix component-wise multiplication tests", OP_COMP_MUL, false},
1269*35238bceSAndroid Build Coastguard Worker         {"unary_addition", "Matrix unary addition tests", OP_UNARY_PLUS, false},
1270*35238bceSAndroid Build Coastguard Worker         {"negation", "Matrix negation tests", OP_NEGATION, false},
1271*35238bceSAndroid Build Coastguard Worker         {"pre_increment", "Matrix prefix increment tests", OP_PRE_INCREMENT, false},
1272*35238bceSAndroid Build Coastguard Worker         {"pre_decrement", "Matrix prefix decrement tests", OP_PRE_DECREMENT, false},
1273*35238bceSAndroid Build Coastguard Worker         {"post_increment", "Matrix postfix increment tests", OP_POST_INCREMENT, false},
1274*35238bceSAndroid Build Coastguard Worker         {"post_decrement", "Matrix postfix decrement tests", OP_POST_DECREMENT, false},
1275*35238bceSAndroid Build Coastguard Worker         {"add_assign", "Matrix add into tests", OP_ADD_INTO, false},
1276*35238bceSAndroid Build Coastguard Worker         {"sub_assign", "Matrix subtract from tests", OP_SUBTRACT_FROM, false},
1277*35238bceSAndroid Build Coastguard Worker         {"mul_assign", "Matrix multiply into tests", OP_MULTIPLY_INTO, false},
1278*35238bceSAndroid Build Coastguard Worker         {"div_assign", "Matrix divide into tests", OP_DIVIDE_INTO, false},
1279*35238bceSAndroid Build Coastguard Worker     };
1280*35238bceSAndroid Build Coastguard Worker 
1281*35238bceSAndroid Build Coastguard Worker     struct InputTypeSpec
1282*35238bceSAndroid Build Coastguard Worker     {
1283*35238bceSAndroid Build Coastguard Worker         const char *name;
1284*35238bceSAndroid Build Coastguard Worker         const char *desc;
1285*35238bceSAndroid Build Coastguard Worker         InputType type;
1286*35238bceSAndroid Build Coastguard Worker     };
1287*35238bceSAndroid Build Coastguard Worker     static const InputTypeSpec extendedInputTypes[] = {{"const", "Constant matrix input", INPUTTYPE_CONST},
1288*35238bceSAndroid Build Coastguard Worker                                                        {"uniform", "Uniform matrix input", INPUTTYPE_UNIFORM},
1289*35238bceSAndroid Build Coastguard Worker                                                        {"dynamic", "Dynamic matrix input", INPUTTYPE_DYNAMIC}};
1290*35238bceSAndroid Build Coastguard Worker     static const InputTypeSpec reducedInputTypes[]  = {{"dynamic", "Dynamic matrix input", INPUTTYPE_DYNAMIC}};
1291*35238bceSAndroid Build Coastguard Worker 
1292*35238bceSAndroid Build Coastguard Worker     static const DataType matrixTypes[] = {TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT4};
1293*35238bceSAndroid Build Coastguard Worker 
1294*35238bceSAndroid Build Coastguard Worker     static const Precision precisions[] = {PRECISION_LOWP, PRECISION_MEDIUMP, PRECISION_HIGHP};
1295*35238bceSAndroid Build Coastguard Worker 
1296*35238bceSAndroid Build Coastguard Worker     for (int opNdx = 0; opNdx < DE_LENGTH_OF_ARRAY(ops); opNdx++)
1297*35238bceSAndroid Build Coastguard Worker     {
1298*35238bceSAndroid Build Coastguard Worker         const InputTypeSpec *inTypeList =
1299*35238bceSAndroid Build Coastguard Worker             (ops[opNdx].extendedInputTypeCases) ? (extendedInputTypes) : (reducedInputTypes);
1300*35238bceSAndroid Build Coastguard Worker         const int inTypeListSize    = (ops[opNdx].extendedInputTypeCases) ? (DE_LENGTH_OF_ARRAY(extendedInputTypes)) :
1301*35238bceSAndroid Build Coastguard Worker                                                                             (DE_LENGTH_OF_ARRAY(reducedInputTypes));
1302*35238bceSAndroid Build Coastguard Worker         const MatrixOp op           = ops[opNdx].op;
1303*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *opGroup = new tcu::TestCaseGroup(m_testCtx, ops[opNdx].name, ops[opNdx].desc);
1304*35238bceSAndroid Build Coastguard Worker 
1305*35238bceSAndroid Build Coastguard Worker         addChild(opGroup);
1306*35238bceSAndroid Build Coastguard Worker 
1307*35238bceSAndroid Build Coastguard Worker         for (int inTypeNdx = 0; inTypeNdx < inTypeListSize; inTypeNdx++)
1308*35238bceSAndroid Build Coastguard Worker         {
1309*35238bceSAndroid Build Coastguard Worker             const InputType inputType = inTypeList[inTypeNdx].type;
1310*35238bceSAndroid Build Coastguard Worker 
1311*35238bceSAndroid Build Coastguard Worker             for (int matTypeNdx = 0; matTypeNdx < DE_LENGTH_OF_ARRAY(matrixTypes); matTypeNdx++)
1312*35238bceSAndroid Build Coastguard Worker             {
1313*35238bceSAndroid Build Coastguard Worker                 DataType matType        = matrixTypes[matTypeNdx];
1314*35238bceSAndroid Build Coastguard Worker                 const char *matTypeName = getDataTypeName(matType);
1315*35238bceSAndroid Build Coastguard Worker 
1316*35238bceSAndroid Build Coastguard Worker                 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++)
1317*35238bceSAndroid Build Coastguard Worker                 {
1318*35238bceSAndroid Build Coastguard Worker                     Precision precision  = precisions[precNdx];
1319*35238bceSAndroid Build Coastguard Worker                     const char *precName = getPrecisionName(precision);
1320*35238bceSAndroid Build Coastguard Worker                     string baseName = string(inTypeList[inTypeNdx].name) + "_" + precName + "_" + matTypeName + "_";
1321*35238bceSAndroid Build Coastguard Worker                     ShaderInput matIn(inputType, matType, precision);
1322*35238bceSAndroid Build Coastguard Worker 
1323*35238bceSAndroid Build Coastguard Worker                     if (isOperationMatrixScalar(op))
1324*35238bceSAndroid Build Coastguard Worker                     {
1325*35238bceSAndroid Build Coastguard Worker                         // Matrix-scalar \note For div cases we use uniform input.
1326*35238bceSAndroid Build Coastguard Worker                         ShaderInput scalarIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, TYPE_FLOAT,
1327*35238bceSAndroid Build Coastguard Worker                                              precision);
1328*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),
1329*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-scalar case", matIn, scalarIn, op, true));
1330*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),
1331*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-scalar case", matIn, scalarIn, op, false));
1332*35238bceSAndroid Build Coastguard Worker                     }
1333*35238bceSAndroid Build Coastguard Worker 
1334*35238bceSAndroid Build Coastguard Worker                     if (isOperationMatrixVector(op))
1335*35238bceSAndroid Build Coastguard Worker                     {
1336*35238bceSAndroid Build Coastguard Worker                         // Matrix-vector.
1337*35238bceSAndroid Build Coastguard Worker                         DataType vecType = getDataTypeFloatVec(getDataTypeMatrixNumColumns(matType));
1338*35238bceSAndroid Build Coastguard Worker                         ShaderInput vecIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, vecType, precision);
1339*35238bceSAndroid Build Coastguard Worker 
1340*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(
1341*35238bceSAndroid Build Coastguard Worker                             new ShaderMatrixCase(m_context, (baseName + getDataTypeName(vecType) + "_vertex").c_str(),
1342*35238bceSAndroid Build Coastguard Worker                                                  "Matrix-vector case", matIn, vecIn, op, true));
1343*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(
1344*35238bceSAndroid Build Coastguard Worker                             new ShaderMatrixCase(m_context, (baseName + getDataTypeName(vecType) + "_fragment").c_str(),
1345*35238bceSAndroid Build Coastguard Worker                                                  "Matrix-vector case", matIn, vecIn, op, false));
1346*35238bceSAndroid Build Coastguard Worker 
1347*35238bceSAndroid Build Coastguard Worker                         // Vector-matrix.
1348*35238bceSAndroid Build Coastguard Worker                         string vecMatName = string(inTypeList[inTypeNdx].name) + "_" + precName + "_" +
1349*35238bceSAndroid Build Coastguard Worker                                             getDataTypeName(vecType) + "_" + matTypeName;
1350*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (vecMatName + "_vertex").c_str(),
1351*35238bceSAndroid Build Coastguard Worker                                                                "Vector-matrix case", vecIn, matIn, op, true));
1352*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (vecMatName + "_fragment").c_str(),
1353*35238bceSAndroid Build Coastguard Worker                                                                "Vector-matrix case", vecIn, matIn, op, false));
1354*35238bceSAndroid Build Coastguard Worker                     }
1355*35238bceSAndroid Build Coastguard Worker 
1356*35238bceSAndroid Build Coastguard Worker                     if (isOperationMatrixMatrix(op))
1357*35238bceSAndroid Build Coastguard Worker                     {
1358*35238bceSAndroid Build Coastguard Worker                         // Matrix-matrix.
1359*35238bceSAndroid Build Coastguard Worker                         ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType,
1360*35238bceSAndroid Build Coastguard Worker                                                precision);
1361*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (baseName + matTypeName + "_vertex").c_str(),
1362*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-matrix case", matIn, otherMatIn, op, true));
1363*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context,
1364*35238bceSAndroid Build Coastguard Worker                                                                (baseName + matTypeName + "_fragment").c_str(),
1365*35238bceSAndroid Build Coastguard Worker                                                                "Matrix-matrix case", matIn, otherMatIn, op, false));
1366*35238bceSAndroid Build Coastguard Worker                     }
1367*35238bceSAndroid Build Coastguard Worker 
1368*35238bceSAndroid Build Coastguard Worker                     if (isOperationUnary(op))
1369*35238bceSAndroid Build Coastguard Worker                     {
1370*35238bceSAndroid Build Coastguard Worker                         // op matrix
1371*35238bceSAndroid Build Coastguard Worker                         ShaderInput voidInput(INPUTTYPE_LAST, TYPE_LAST, PRECISION_LAST);
1372*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "vertex").c_str(), "Matrix case",
1373*35238bceSAndroid Build Coastguard Worker                                                                matIn, voidInput, op, true));
1374*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "fragment").c_str(),
1375*35238bceSAndroid Build Coastguard Worker                                                                "Matrix case", matIn, voidInput, op, false));
1376*35238bceSAndroid Build Coastguard Worker                     }
1377*35238bceSAndroid Build Coastguard Worker 
1378*35238bceSAndroid Build Coastguard Worker                     if (isOperationAssignment(op))
1379*35238bceSAndroid Build Coastguard Worker                     {
1380*35238bceSAndroid Build Coastguard Worker                         ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType,
1381*35238bceSAndroid Build Coastguard Worker                                                precision);
1382*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "vertex").c_str(),
1383*35238bceSAndroid Build Coastguard Worker                                                                "Matrix assignment case", matIn, otherMatIn, op, true));
1384*35238bceSAndroid Build Coastguard Worker                         opGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "fragment").c_str(),
1385*35238bceSAndroid Build Coastguard Worker                                                                "Matrix assignment case", matIn, otherMatIn, op, false));
1386*35238bceSAndroid Build Coastguard Worker                     }
1387*35238bceSAndroid Build Coastguard Worker                 }
1388*35238bceSAndroid Build Coastguard Worker             }
1389*35238bceSAndroid Build Coastguard Worker         }
1390*35238bceSAndroid Build Coastguard Worker     }
1391*35238bceSAndroid Build Coastguard Worker }
1392*35238bceSAndroid Build Coastguard Worker 
1393*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1394*35238bceSAndroid Build Coastguard Worker } // namespace gles2
1395*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1396*35238bceSAndroid Build Coastguard Worker 
1397*35238bceSAndroid Build Coastguard Worker #if defined(_MSC_VER) && _MSC_FULL_VER == 191125507
1398*35238bceSAndroid Build Coastguard Worker // Work around crbug.com/759402 which is a code-gen bug in VC++ 2017, version
1399*35238bceSAndroid Build Coastguard Worker // 15.3.2.
1400*35238bceSAndroid Build Coastguard Worker #pragma optimize("", off)
1401*35238bceSAndroid Build Coastguard Worker #endif
1402