1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Shader matrix arithmetic tests.
39 *//*--------------------------------------------------------------------*/
41 #include "vktShaderRenderMatrixTests.hpp"
43 #include "vktShaderRender.hpp"
44 #include "tcuVector.hpp"
45 #include "tcuMatrix.hpp"
46 #include "tcuMatrixUtil.hpp"
47 #include "deStringUtil.hpp"
73 // Uniform / constant values for tests.
74 // \note Input1 should not contain 0 components as it is used as divisor in div cases.
75 static const float s_constInFloat[2] = { 0.5f, -0.2f };
76 static const Vec2 s_constInVec2[2] = { Vec2(1.2f, 0.5f), Vec2(0.5f, 1.0f) };
77 static const Vec3 s_constInVec3[2] = { Vec3(1.1f, 0.1f, 0.5f), Vec3(-0.2f, 0.5f, 0.8f) };
78 static const Vec4 s_constInVec4[2] = { Vec4(1.4f, 0.2f, -0.5f, 0.7f), Vec4(0.2f, -1.0f, 0.5f, 0.8f) };
80 static const float s_constInMat2x2[2][4] =
91 static const float s_constInMat3x2[2][6] =
102 static const float s_constInMat4x2[2][8] =
105 -0.2f, 0.5f, 0.0f, -1.0f,
106 1.2f, -0.5f, 0.3f, -0.9f,
109 1.0f, 0.1f, -1.1f, 0.6f,
110 0.8f, -1.2f, -1.1f, 0.7f,
113 static const float s_constInMat2x3[2][6] =
126 static const float s_constInMat3x3[2][9] =
139 static const float s_constInMat4x3[2][12] =
142 -0.9f, 0.0f, 0.6f, 0.2f,
143 0.9f, -0.1f, -0.3f, -0.7f,
144 -0.1f, 0.1f, 1.0f, 0.0f,
147 0.5f, 0.7f, 0.7f, 1.2f,
148 1.1f, 0.1f, 1.0f, -1.0f,
149 -0.2f, -0.2f, -0.3f, -0.5f,
152 static const float s_constInMat2x4[2][8] =
167 static const float s_constInMat3x4[2][12] =
182 static const float s_constInMat4x4[2][16] =
185 0.3f, 0.9f, -0.2f, 1.0f,
186 -0.4f, -0.6f, 0.6f, -1.0f,
187 -0.9f, -0.1f, 0.3f, -0.2f,
188 -0.3f, -0.9f, 1.0f, 0.1f,
191 0.4f, -0.7f, -0.8f, 0.7f,
192 -0.4f, -0.8f, 0.6f, -0.3f,
193 0.7f, -1.0f, 0.1f, -0.3f,
194 0.2f, 0.6f, 0.4f, -1.0f,
198 namespace MatrixCaseUtils
212 ShaderInput (InputType inputType_, DataType dataType_, Precision precision_)
213 : inputType (inputType_)
214 , dataType (dataType_)
215 , precision (precision_)
253 #define DECLARE_TYPE_TRAIT(DATATYPE, TYPE) \
255 struct TypeTraits<DATATYPE> { \
259 DECLARE_TYPE_TRAIT(TYPE_FLOAT, float);
260 DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC2, tcu::Vec2);
261 DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC3, tcu::Vec3);
262 DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC4, tcu::Vec4);
263 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2, tcu::Mat2);
264 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X3, tcu::Mat2x3);
265 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X4, tcu::Mat2x4);
266 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X2, tcu::Mat3x2);
267 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3, tcu::Mat3);
268 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X4, tcu::Mat3x4);
269 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X2, tcu::Mat4x2);
270 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X3, tcu::Mat4x3);
271 DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4, tcu::Mat4);
277 OPERATIONTYPE_BINARY_OPERATOR = 0,
278 OPERATIONTYPE_BINARY_FUNCTION,
279 OPERATIONTYPE_UNARY_PREFIX_OPERATOR,
280 OPERATIONTYPE_UNARY_POSTFIX_OPERATOR,
281 OPERATIONTYPE_UNARY_FUNCTION,
282 OPERATIONTYPE_ASSIGNMENT,
287 static const char* getOperationName (MatrixOp op)
291 case OP_ADD: return "+";
292 case OP_SUB: return "-";
293 case OP_MUL: return "*";
294 case OP_DIV: return "/";
295 case OP_COMP_MUL: return "matrixCompMult";
296 case OP_OUTER_PRODUCT: return "outerProduct";
297 case OP_TRANSPOSE: return "transpose";
298 case OP_INVERSE: return "inverse";
299 case OP_DETERMINANT: return "determinant";
300 case OP_UNARY_PLUS: return "+";
301 case OP_NEGATION: return "-";
302 case OP_PRE_INCREMENT: return "++";
303 case OP_PRE_DECREMENT: return "--";
304 case OP_POST_INCREMENT: return "++";
305 case OP_POST_DECREMENT: return "--";
306 case OP_ADD_INTO: return "+=";
307 case OP_SUBTRACT_FROM: return "-=";
308 case OP_MULTIPLY_INTO: return "*=";
309 case OP_DIVIDE_INTO: return "/=";
317 static OperationType getOperationType (MatrixOp op)
321 case OP_ADD: return OPERATIONTYPE_BINARY_OPERATOR;
322 case OP_SUB: return OPERATIONTYPE_BINARY_OPERATOR;
323 case OP_MUL: return OPERATIONTYPE_BINARY_OPERATOR;
324 case OP_DIV: return OPERATIONTYPE_BINARY_OPERATOR;
325 case OP_COMP_MUL: return OPERATIONTYPE_BINARY_FUNCTION;
326 case OP_OUTER_PRODUCT: return OPERATIONTYPE_BINARY_FUNCTION;
327 case OP_TRANSPOSE: return OPERATIONTYPE_UNARY_FUNCTION;
328 case OP_INVERSE: return OPERATIONTYPE_UNARY_FUNCTION;
329 case OP_DETERMINANT: return OPERATIONTYPE_UNARY_FUNCTION;
330 case OP_UNARY_PLUS: return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
331 case OP_NEGATION: return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
332 case OP_PRE_INCREMENT: return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
333 case OP_PRE_DECREMENT: return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
334 case OP_POST_INCREMENT: return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
335 case OP_POST_DECREMENT: return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
336 case OP_ADD_INTO: return OPERATIONTYPE_ASSIGNMENT;
337 case OP_SUBTRACT_FROM: return OPERATIONTYPE_ASSIGNMENT;
338 case OP_MULTIPLY_INTO: return OPERATIONTYPE_ASSIGNMENT;
339 case OP_DIVIDE_INTO: return OPERATIONTYPE_ASSIGNMENT;
342 return OPERATIONTYPE_LAST;
348 TESTMATRIXTYPE_DEFAULT = 0,
349 TESTMATRIXTYPE_NEGATED,
350 TESTMATRIXTYPE_INCREMENTED,
351 TESTMATRIXTYPE_DECREMENTED,
352 TESTMATRIXTYPE_NEGATED_INCREMENTED,
353 TESTMATRIXTYPE_INCREMENTED_LESS,
358 static TestMatrixType getOperationTestMatrixType (MatrixOp op)
362 case OP_ADD: return TESTMATRIXTYPE_DEFAULT;
363 case OP_SUB: return TESTMATRIXTYPE_DEFAULT;
364 case OP_MUL: return TESTMATRIXTYPE_DEFAULT;
365 case OP_DIV: return TESTMATRIXTYPE_DEFAULT;
366 case OP_COMP_MUL: return TESTMATRIXTYPE_DEFAULT;
367 case OP_OUTER_PRODUCT: return TESTMATRIXTYPE_DEFAULT;
368 case OP_TRANSPOSE: return TESTMATRIXTYPE_DEFAULT;
369 case OP_INVERSE: return TESTMATRIXTYPE_DEFAULT;
370 case OP_DETERMINANT: return TESTMATRIXTYPE_DEFAULT;
371 case OP_UNARY_PLUS: return TESTMATRIXTYPE_DECREMENTED;
372 case OP_NEGATION: return TESTMATRIXTYPE_NEGATED_INCREMENTED;
373 case OP_PRE_INCREMENT: return TESTMATRIXTYPE_NEGATED;
374 case OP_PRE_DECREMENT: return TESTMATRIXTYPE_INCREMENTED;
375 case OP_POST_INCREMENT: return TESTMATRIXTYPE_NEGATED;
376 case OP_POST_DECREMENT: return TESTMATRIXTYPE_DEFAULT;
377 case OP_ADD_INTO: return TESTMATRIXTYPE_DEFAULT;
378 case OP_SUBTRACT_FROM: return TESTMATRIXTYPE_INCREMENTED_LESS;
379 case OP_MULTIPLY_INTO: return TESTMATRIXTYPE_NEGATED;
380 case OP_DIVIDE_INTO: return TESTMATRIXTYPE_DECREMENTED;
384 return TESTMATRIXTYPE_LAST;
388 static bool isOperationBinary (MatrixOp op)
390 return getOperationType(op) == OPERATIONTYPE_BINARY_OPERATOR ||
391 getOperationType(op) == OPERATIONTYPE_BINARY_FUNCTION ||
392 getOperationType(op) == OPERATIONTYPE_ASSIGNMENT;
395 static bool isOperationMatrixScalar (MatrixOp op)
397 return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV;
400 static bool isOperationMatrixVector (MatrixOp op)
405 static bool isOperationArithmeticMatrixMatrix (MatrixOp op)
410 static bool isOperationComponentwiseMatrixMatrix (MatrixOp op)
412 return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV || op == OP_COMP_MUL;
415 static bool isOperationVectorVector (MatrixOp op)
417 return op == OP_OUTER_PRODUCT;
420 static bool isOperationUnaryAnyMatrix (MatrixOp op)
422 return op == OP_TRANSPOSE ||
423 op == OP_UNARY_PLUS ||
425 op == OP_PRE_INCREMENT ||
426 op == OP_PRE_DECREMENT ||
427 op == OP_POST_INCREMENT ||
428 op == OP_POST_DECREMENT;
431 static bool isOperationUnarySymmetricMatrix (MatrixOp op)
433 return op == OP_INVERSE || op == OP_DETERMINANT;
436 static bool isOperationValueModifying (MatrixOp op)
438 return op == OP_PRE_INCREMENT ||
439 op == OP_PRE_DECREMENT ||
440 op == OP_POST_INCREMENT ||
441 op == OP_POST_DECREMENT;
444 static bool isOperationAssignment (MatrixOp op)
446 return op == OP_ADD_INTO ||
447 op == OP_SUBTRACT_FROM ||
448 op == OP_MULTIPLY_INTO ||
449 op == OP_DIVIDE_INTO;
452 static bool isOperationAssignmentAnyMatrix (MatrixOp op)
454 return op == OP_ADD_INTO ||
455 op == OP_SUBTRACT_FROM ||
456 op == OP_DIVIDE_INTO;
459 static bool isOperationAssignmentSymmetricMatrix (MatrixOp op)
461 return op == OP_MULTIPLY_INTO;
468 OPERATIONNATURE_PURE = 0,
469 OPERATIONNATURE_MUTATING,
470 OPERATIONNATURE_ASSIGNMENT,
475 static OperationNature getOperationNature (MatrixOp op)
477 if (isOperationAssignment(op))
478 return OPERATIONNATURE_ASSIGNMENT;
480 if (isOperationValueModifying(op))
481 return OPERATIONNATURE_MUTATING;
483 return OPERATIONNATURE_PURE;
486 // Input value loader.
488 template <int InputT, int DataT>
489 typename TypeTraits<DataT>::Type getInputValue (const ShaderEvalContext& evalCtx, int inputNdx);
491 template <> inline float getInputValue<INPUTTYPE_CONST, TYPE_FLOAT> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInFloat[inputNdx]; }
492 template <> inline tcu::Vec2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC2> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec2[inputNdx]; }
493 template <> inline tcu::Vec3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC3> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec3[inputNdx]; }
494 template <> inline tcu::Vec4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_VEC4> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec4[inputNdx]; }
496 template <> inline tcu::Mat2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT2> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2(s_constInMat2x2[inputNdx]); }
497 template <> inline tcu::Mat2x3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT2X3> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2x3(s_constInMat2x3[inputNdx]); }
498 template <> inline tcu::Mat2x4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT2X4> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2x4(s_constInMat2x4[inputNdx]); }
499 template <> inline tcu::Mat3x2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT3X2> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3x2(s_constInMat3x2[inputNdx]); }
500 template <> inline tcu::Mat3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT3> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3(s_constInMat3x3[inputNdx]); }
501 template <> inline tcu::Mat3x4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT3X4> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3x4(s_constInMat3x4[inputNdx]); }
502 template <> inline tcu::Mat4x2 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT4X2> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4x2(s_constInMat4x2[inputNdx]); }
503 template <> inline tcu::Mat4x3 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT4X3> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4x3(s_constInMat4x3[inputNdx]); }
504 template <> inline tcu::Mat4 getInputValue<INPUTTYPE_CONST, TYPE_FLOAT_MAT4> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4(s_constInMat4x4[inputNdx]); }
506 template <> inline float getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.x(); }
507 template <> inline tcu::Vec2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC2> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1); }
508 template <> inline tcu::Vec3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC3> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1, 2); }
509 template <> inline tcu::Vec4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_VEC4> (const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1, 2, 3); }
511 template <> inline tcu::Mat2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2> (const ShaderEvalContext& evalCtx, int inputNdx)
513 DE_UNREF(inputNdx); // Not used.
515 m.setColumn(0, evalCtx.in[0].swizzle(0,1));
516 m.setColumn(1, evalCtx.in[1].swizzle(0,1));
520 template <> inline tcu::Mat2x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X3> (const ShaderEvalContext& evalCtx, int inputNdx)
522 DE_UNREF(inputNdx); // Not used.
524 m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
525 m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
529 template <> inline tcu::Mat2x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X4> (const ShaderEvalContext& evalCtx, int inputNdx)
531 DE_UNREF(inputNdx); // Not used.
533 m.setColumn(0, evalCtx.in[0]);
534 m.setColumn(1, evalCtx.in[1]);
538 template <> inline tcu::Mat3x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X2> (const ShaderEvalContext& evalCtx, int inputNdx)
540 DE_UNREF(inputNdx); // Not used.
542 m.setColumn(0, evalCtx.in[0].swizzle(0,1));
543 m.setColumn(1, evalCtx.in[1].swizzle(0,1));
544 m.setColumn(2, evalCtx.in[2].swizzle(0,1));
548 template <> inline tcu::Mat3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3> (const ShaderEvalContext& evalCtx, int inputNdx)
550 DE_UNREF(inputNdx); // Not used.
552 m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
553 m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
554 m.setColumn(2, evalCtx.in[2].swizzle(0,1,2));
558 template <> inline tcu::Mat3x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X4> (const ShaderEvalContext& evalCtx, int inputNdx)
560 DE_UNREF(inputNdx); // Not used.
562 m.setColumn(0, evalCtx.in[0]);
563 m.setColumn(1, evalCtx.in[1]);
564 m.setColumn(2, evalCtx.in[2]);
568 template <> inline tcu::Mat4x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X2> (const ShaderEvalContext& evalCtx, int inputNdx)
570 DE_UNREF(inputNdx); // Not used.
572 m.setColumn(0, evalCtx.in[0].swizzle(0,1));
573 m.setColumn(1, evalCtx.in[1].swizzle(0,1));
574 m.setColumn(2, evalCtx.in[2].swizzle(0,1));
575 m.setColumn(3, evalCtx.in[3].swizzle(0,1));
579 template <> inline tcu::Mat4x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X3> (const ShaderEvalContext& evalCtx, int inputNdx)
581 DE_UNREF(inputNdx); // Not used.
583 m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
584 m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
585 m.setColumn(2, evalCtx.in[2].swizzle(0,1,2));
586 m.setColumn(3, evalCtx.in[3].swizzle(0,1,2));
590 template <> inline tcu::Mat4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4> (const ShaderEvalContext& evalCtx, int inputNdx)
592 DE_UNREF(inputNdx); // Not used.
594 m.setColumn(0, evalCtx.in[0]);
595 m.setColumn(1, evalCtx.in[1]);
596 m.setColumn(2, evalCtx.in[2]);
597 m.setColumn(3, evalCtx.in[3]);
601 // Reduction from expression result to vec3.
603 inline tcu::Vec3 reduceToVec3 (const tcu::Vec2& value) { return value.swizzle(0,1,0); }
604 inline tcu::Vec3 reduceToVec3 (const tcu::Vec3& value) { return value; }
605 inline tcu::Vec3 reduceToVec3 (const tcu::Vec4& value) { return tcu::Vec3(value.x(), value.y(), value.z()+value.w()); }
606 inline tcu::Vec3 reduceToVec3 (const tcu::Mat2& value) { return tcu::Vec3(value(0, 0), value(0, 1), value(1, 0)+value(1, 1)); }
607 inline tcu::Vec3 reduceToVec3 (const tcu::Mat2x3& value) { return value.getColumn(0) + value.getColumn(1); }
608 inline tcu::Vec3 reduceToVec3 (const tcu::Mat2x4& value) { return value.getColumn(0).swizzle(0,1,2) + value.getColumn(1).swizzle(1,2,3); }
609 inline tcu::Vec3 reduceToVec3 (const tcu::Mat3x2& value) { return tcu::Vec3(value(0,0)+value(1,0), value(0,1)+value(1,1), value(0,2)+value(1,2)); }
610 inline tcu::Vec3 reduceToVec3 (const tcu::Mat3& value) { return value.getColumn(0) + value.getColumn(1) + value.getColumn(2); }
611 inline tcu::Vec3 reduceToVec3 (const tcu::Mat3x4& value) { return value.getColumn(0).swizzle(0,1,2) + value.getColumn(1).swizzle(1,2,3) + value.getColumn(2).swizzle(2,3,0); }
612 inline tcu::Vec3 reduceToVec3 (const tcu::Mat4x2& value) { return tcu::Vec3(value(0,0)+value(1,0)+value(0,3), value(0,1)+value(1,1)+value(1,3), value(0,2)+value(1,2)); }
613 inline tcu::Vec3 reduceToVec3 (const tcu::Mat4x3& value) { return value.getColumn(0) + value.getColumn(1) + value.getColumn(2) + value.getColumn(3); }
614 inline tcu::Vec3 reduceToVec3 (const tcu::Mat4& value) { return value.getColumn(0).swizzle(0,1,2) + value.getColumn(1).swizzle(1,2,3) + value.getColumn(2).swizzle(2,3,0) + value.getColumn(3).swizzle(3,0,1); }
618 template <typename T, int Rows, int Cols>
619 tcu::Matrix<T, Rows, Cols> matrixCompMult (const tcu::Matrix<T, Rows, Cols>& a, const tcu::Matrix<T, Rows, Cols>& b)
621 tcu::Matrix<T, Rows, Cols> retVal;
623 for (int r = 0; r < Rows; ++r)
624 for (int c = 0; c < Cols; ++c)
625 retVal(r,c) = a(r,c) * b(r, c);
632 template <typename T, int Rows, int Cols>
633 tcu::Matrix<T, Cols, Rows> outerProduct (const tcu::Vector<T, Cols>& a, const tcu::Vector<T, Rows>& b)
635 tcu::Matrix<T, Rows, Cols> retVal;
637 for (int r = 0; r < Rows; ++r)
638 for (int c = 0; c < Cols; ++c)
639 retVal(r,c) = a[c] * b[r];
641 return transpose(retVal); // to gl-form (column-major)
647 float determinant (const tcu::Matrix<float, Size, Size>& mat);
650 float determinant<2> (const tcu::Matrix<float, 2, 2>& mat)
652 return mat(0,0) * mat(1,1) - mat(1,0) * mat(0,1);
656 float determinant<3> (const tcu::Matrix<float, 3, 3>& mat)
658 return + mat(0,0) * mat(1,1) * mat(2,2)
659 + mat(0,1) * mat(1,2) * mat(2,0)
660 + mat(0,2) * mat(1,0) * mat(2,1)
661 - mat(0,0) * mat(1,2) * mat(2,1)
662 - mat(0,1) * mat(1,0) * mat(2,2)
663 - mat(0,2) * mat(1,1) * mat(2,0);
667 float determinant<4> (const tcu::Matrix<float, 4, 4>& mat)
669 const float minorMatrices[4][3*3] =
672 mat(1,1), mat(2,1), mat(3,1),
673 mat(1,2), mat(2,2), mat(3,2),
674 mat(1,3), mat(2,3), mat(3,3),
677 mat(1,0), mat(2,0), mat(3,0),
678 mat(1,2), mat(2,2), mat(3,2),
679 mat(1,3), mat(2,3), mat(3,3),
682 mat(1,0), mat(2,0), mat(3,0),
683 mat(1,1), mat(2,1), mat(3,1),
684 mat(1,3), mat(2,3), mat(3,3),
687 mat(1,0), mat(2,0), mat(3,0),
688 mat(1,1), mat(2,1), mat(3,1),
689 mat(1,2), mat(2,2), mat(3,2),
693 return + mat(0,0) * determinant(tcu::Mat3(minorMatrices[0]))
694 - mat(0,1) * determinant(tcu::Mat3(minorMatrices[1]))
695 + mat(0,2) * determinant(tcu::Mat3(minorMatrices[2]))
696 - mat(0,3) * determinant(tcu::Mat3(minorMatrices[3]));
702 tcu::Matrix<float, Size, Size> inverse (const tcu::Matrix<float, Size, Size>& mat);
705 tcu::Matrix<float, 2, 2> inverse<2> (const tcu::Matrix<float, 2, 2>& mat)
707 const float det = determinant(mat);
708 tcu::Matrix<float, 2, 2> retVal;
710 DE_ASSERT(det != 0.0f);
712 retVal(0, 0) = mat(1, 1) / det;
713 retVal(0, 1) = -mat(0, 1) / det;
714 retVal(1, 0) = -mat(1, 0) / det;
715 retVal(1, 1) = mat(0, 0) / det;
721 tcu::Matrix<float, 3, 3> inverse<3> (const tcu::Matrix<float, 3, 3>& mat)
723 // Blockwise inversion
725 DE_ASSERT(determinant(mat) != 0.0f);
727 const float areaA[2*2] =
732 const float areaB[2] =
737 const float areaC[2] =
741 const float areaD[1] =
745 const float nullField[4] = { 0.0f };
747 const tcu::Matrix<float, 2, 2> invA = inverse(tcu::Matrix<float, 2, 2>(areaA));
748 const tcu::Matrix<float, 2, 1> matB = tcu::Matrix<float, 2, 1>(areaB);
749 const tcu::Matrix<float, 1, 2> matC = tcu::Matrix<float, 1, 2>(areaC);
750 const tcu::Matrix<float, 1, 1> matD = tcu::Matrix<float, 1, 1>(areaD);
752 const float schurComplement = 1.0f / (matD - matC*invA*matB)(0,0);
753 const tcu::Matrix<float, 2, 2> zeroMat = Mat2(nullField);
755 const tcu::Matrix<float, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
756 const tcu::Matrix<float, 2, 1> blockB = (zeroMat-invA)*matB*schurComplement;
757 const tcu::Matrix<float, 1, 2> blockC = matC*invA*(-schurComplement);
758 const float blockD = schurComplement;
760 const float result[3*3] =
762 blockA(0,0), blockA(0,1), blockB(0,0),
763 blockA(1,0), blockA(1,1), blockB(1,0),
764 blockC(0,0), blockC(0,1), blockD,
771 tcu::Matrix<float, 4, 4> inverse<4> (const tcu::Matrix<float, 4, 4>& mat)
773 // Blockwise inversion
775 DE_ASSERT(determinant(mat) != 0.0f);
777 const float areaA[2*2] =
782 const float areaB[2*2] =
787 const float areaC[2*2] =
792 const float areaD[2*2] =
797 const float nullField[4] = { 0.0f };
799 const tcu::Matrix<float, 2, 2> invA = inverse(Mat2(areaA));
800 const tcu::Matrix<float, 2, 2> matB = Mat2(areaB);
801 const tcu::Matrix<float, 2, 2> matC = Mat2(areaC);
802 const tcu::Matrix<float, 2, 2> matD = Mat2(areaD);
804 const tcu::Matrix<float, 2, 2> schurComplement = inverse(matD - matC*invA*matB);
805 const tcu::Matrix<float, 2, 2> zeroMat = Mat2(nullField);
807 const tcu::Matrix<float, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
808 const tcu::Matrix<float, 2, 2> blockB = (zeroMat-invA)*matB*schurComplement;
809 const tcu::Matrix<float, 2, 2> blockC = (zeroMat-schurComplement)*matC*invA;
810 const tcu::Matrix<float, 2, 2> blockD = schurComplement;
812 const float result[4*4] =
814 blockA(0,0), blockA(0,1), blockB(0,0), blockB(0,1),
815 blockA(1,0), blockA(1,1), blockB(1,0), blockB(1,1),
816 blockC(0,0), blockC(0,1), blockD(0,0), blockD(0,1),
817 blockC(1,0), blockC(1,1), blockD(1,0), blockD(1,1),
825 template <typename T, int Rows, int Cols>
826 tcu::Matrix<T, Rows, Cols> negate (const tcu::Matrix<T, Rows, Cols>& mat)
828 tcu::Matrix<T, Rows, Cols> retVal;
830 for (int r = 0; r < Rows; ++r)
831 for (int c = 0; c < Cols; ++c)
832 retVal(r,c) = -mat(r, c);
837 // increment/decrement
839 template <typename T, int Rows, int Cols>
840 tcu::Matrix<T, Rows, Cols> increment (const tcu::Matrix<T, Rows, Cols>& mat)
842 tcu::Matrix<T, Rows, Cols> retVal;
844 for (int r = 0; r < Rows; ++r)
845 for (int c = 0; c < Cols; ++c)
846 retVal(r,c) = mat(r, c) + 1.0f;
851 template <typename T, int Rows, int Cols>
852 tcu::Matrix<T, Rows, Cols> decrement (const tcu::Matrix<T, Rows, Cols>& mat)
854 tcu::Matrix<T, Rows, Cols> retVal;
856 for (int r = 0; r < Rows; ++r)
857 for (int c = 0; c < Cols; ++c)
858 retVal(r,c) = mat(r, c) - 1.0f;
863 // Evaluator template.
865 typedef void (*MatrixShaderEvalFunc) (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type);
867 template <int Op, int In0DataType, int In1DataType>
870 template <int In0DataType, int In1DataType>
871 struct Evaluator<OP_ADD, In0DataType, In1DataType>
873 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
875 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
876 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
877 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
878 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
879 evalCtx.color.xyz() = reduceToVec3(in0 + in1);
883 template <int In0DataType, int In1DataType>
884 struct Evaluator<OP_SUB, In0DataType, In1DataType>
886 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
888 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
889 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
890 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
891 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
892 evalCtx.color.xyz() = reduceToVec3(in0 - in1);
896 template <int In0DataType, int In1DataType>
897 struct Evaluator<OP_MUL, In0DataType, In1DataType>
899 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
901 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
902 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
903 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
904 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
905 evalCtx.color.xyz() = reduceToVec3(in0 * in1);
909 template <int In0DataType, int In1DataType>
910 struct Evaluator<OP_DIV, In0DataType, In1DataType>
912 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
914 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
915 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
916 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
917 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
918 evalCtx.color.xyz() = reduceToVec3(in0 / in1);
922 template <int In0DataType, int In1DataType>
923 struct Evaluator<OP_COMP_MUL, In0DataType, In1DataType>
925 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
927 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
928 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
929 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
930 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
931 evalCtx.color.xyz() = reduceToVec3(matrixCompMult(in0, in1));
935 template <int In0DataType, int In1DataType>
936 struct Evaluator<OP_OUTER_PRODUCT, In0DataType, In1DataType>
938 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
940 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
941 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
942 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
943 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
944 evalCtx.color.xyz() = reduceToVec3(outerProduct(in0, in1));
948 template <int In0DataType, int In1DataType>
949 struct Evaluator<OP_TRANSPOSE, In0DataType, In1DataType>
951 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
954 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
955 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
956 evalCtx.color.xyz() = reduceToVec3(transpose(in0));
960 template <int In0DataType, int In1DataType>
961 struct Evaluator<OP_INVERSE, In0DataType, In1DataType>
963 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
966 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
967 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
968 evalCtx.color.xyz() = reduceToVec3(inverse(in0));
972 template <int In0DataType, int In1DataType>
973 struct Evaluator<OP_DETERMINANT, In0DataType, In1DataType>
975 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
978 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
979 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
980 evalCtx.color.xyz() = Vec3(determinant(in0));
984 template <int In0DataType, int In1DataType>
985 struct Evaluator<OP_UNARY_PLUS, In0DataType, In1DataType>
987 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
990 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
991 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
992 evalCtx.color.xyz() = reduceToVec3(in0);
996 template <int In0DataType, int In1DataType>
997 struct Evaluator<OP_NEGATION, In0DataType, In1DataType>
999 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1002 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1003 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1004 evalCtx.color.xyz() = reduceToVec3(negate(in0));
1008 template <int In0DataType, int In1DataType>
1009 struct Evaluator<OP_PRE_INCREMENT, In0DataType, In1DataType>
1011 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1014 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1015 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1017 // modifying reduction: sum modified value too
1018 evalCtx.color.xyz() = reduceToVec3(increment(in0)) + reduceToVec3(increment(in0));
1022 template <int In0DataType, int In1DataType>
1023 struct Evaluator<OP_PRE_DECREMENT, In0DataType, In1DataType>
1025 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1028 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1029 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1031 // modifying reduction: sum modified value too
1032 evalCtx.color.xyz() = reduceToVec3(decrement(in0)) + reduceToVec3(decrement(in0));
1036 template <int In0DataType, int In1DataType>
1037 struct Evaluator<OP_POST_INCREMENT, In0DataType, In1DataType>
1039 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1042 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1043 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1045 // modifying reduction: sum modified value too
1046 evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(increment(in0));
1050 template <int In0DataType, int In1DataType>
1051 struct Evaluator<OP_POST_DECREMENT, In0DataType, In1DataType>
1053 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1056 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1057 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1059 // modifying reduction: sum modified value too
1060 evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(decrement(in0));
1064 template <int In0DataType, int In1DataType>
1065 struct Evaluator<OP_ADD_INTO, In0DataType, In1DataType>
1067 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1069 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1070 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1071 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
1072 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1073 evalCtx.color.xyz() = reduceToVec3(in0 + in1);
1077 template <int In0DataType, int In1DataType>
1078 struct Evaluator<OP_SUBTRACT_FROM, In0DataType, In1DataType>
1080 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1082 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1083 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1084 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
1085 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1086 evalCtx.color.xyz() = reduceToVec3(in0 - in1);
1090 template <int In0DataType, int In1DataType>
1091 struct Evaluator<OP_MULTIPLY_INTO, In0DataType, In1DataType>
1093 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1095 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1096 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1097 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
1098 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1099 evalCtx.color.xyz() = reduceToVec3(in0 * in1);
1103 template <int In0DataType, int In1DataType>
1104 struct Evaluator<OP_DIVIDE_INTO, In0DataType, In1DataType>
1106 static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
1108 typename TypeTraits<In0DataType>::Type in0 = (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
1109 : getInputValue<INPUTTYPE_CONST, In0DataType>(evalCtx, 0);
1110 typename TypeTraits<In1DataType>::Type in1 = (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
1111 : getInputValue<INPUTTYPE_CONST, In1DataType>(evalCtx, 1);
1112 evalCtx.color.xyz() = reduceToVec3(in0 / in1);
1116 MatrixShaderEvalFunc getEvalFunc (const ShaderInput& in0, const ShaderInput& in1, MatrixOp op)
1118 // Evaluator is selected based on op and input data types.
1119 // For efficient lookup the types and op enums are packed together to form a 19-bit key:
1120 // [18..14 OP] [13..7 TYPE0] [6..0 TYPE1]
1122 DE_STATIC_ASSERT(TYPE_LAST <= (1<<7));
1123 DE_STATIC_ASSERT(OP_LAST <= (1<<5));
1125 #define PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE) (((OP) << 14) | ((IN0DATATYPE) << 7) | (IN1DATATYPE))
1127 #define MAKE_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE) \
1128 case PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE): \
1129 return Evaluator<OP, IN0DATATYPE, IN1DATATYPE>::evaluate
1131 #define MAKE_SCALAR_OPS(IN0DATATYPE, IN1DATATYPE) \
1132 MAKE_EVAL_CASE(OP_ADD, IN0DATATYPE, IN1DATATYPE); \
1133 MAKE_EVAL_CASE(OP_SUB, IN0DATATYPE, IN1DATATYPE); \
1134 MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE); \
1135 MAKE_EVAL_CASE(OP_DIV, IN0DATATYPE, IN1DATATYPE)
1137 #define MAKE_CWISE_OPS(IN0DATATYPE, IN1DATATYPE) \
1138 MAKE_EVAL_CASE(OP_ADD, IN0DATATYPE, IN1DATATYPE); \
1139 MAKE_EVAL_CASE(OP_SUB, IN0DATATYPE, IN1DATATYPE); \
1140 MAKE_EVAL_CASE(OP_DIV, IN0DATATYPE, IN1DATATYPE); \
1141 MAKE_EVAL_CASE(OP_COMP_MUL, IN0DATATYPE, IN1DATATYPE)
1143 #define MAKE_MUL_OP(IN0DATATYPE, IN1DATATYPE) \
1144 MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE)
1146 #define MAKE_VECVEC_OP(IN0DATATYPE, IN1DATATYPE) \
1147 MAKE_EVAL_CASE(OP_OUTER_PRODUCT, IN0DATATYPE, IN1DATATYPE)
1149 #define MAKE_UNARY_OP(IN0DATATYPE) \
1150 MAKE_EVAL_CASE(OP_TRANSPOSE, IN0DATATYPE, TYPE_LAST); \
1151 MAKE_EVAL_CASE(OP_UNARY_PLUS, IN0DATATYPE, TYPE_LAST); \
1152 MAKE_EVAL_CASE(OP_NEGATION, IN0DATATYPE, TYPE_LAST); \
1153 MAKE_EVAL_CASE(OP_PRE_INCREMENT, IN0DATATYPE, TYPE_LAST); \
1154 MAKE_EVAL_CASE(OP_PRE_DECREMENT, IN0DATATYPE, TYPE_LAST); \
1155 MAKE_EVAL_CASE(OP_POST_INCREMENT, IN0DATATYPE, TYPE_LAST); \
1156 MAKE_EVAL_CASE(OP_POST_DECREMENT, IN0DATATYPE, TYPE_LAST)
1158 #define MAKE_UNARY_SYMMETRIC_OP(IN0DATATYPE) \
1159 MAKE_UNARY_OP(IN0DATATYPE); \
1160 MAKE_EVAL_CASE(OP_DETERMINANT, IN0DATATYPE, TYPE_LAST); \
1161 MAKE_EVAL_CASE(OP_INVERSE, IN0DATATYPE, TYPE_LAST)
1163 #define MAKE_ASSIGNMENT_OP(IN0DATATYPE) \
1164 MAKE_EVAL_CASE(OP_ADD_INTO, IN0DATATYPE, IN0DATATYPE); \
1165 MAKE_EVAL_CASE(OP_SUBTRACT_FROM, IN0DATATYPE, IN0DATATYPE); \
1166 MAKE_EVAL_CASE(OP_DIVIDE_INTO, IN0DATATYPE, IN0DATATYPE)
1168 #define MAKE_ASSIGNMENT_SYMMETRIC_OP(IN0DATATYPE) \
1169 MAKE_ASSIGNMENT_OP(IN0DATATYPE); \
1170 MAKE_EVAL_CASE(OP_MULTIPLY_INTO, IN0DATATYPE, IN0DATATYPE)
1172 switch (PACK_EVAL_CASE(op, in0.dataType, in1.dataType))
1175 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2, TYPE_FLOAT);
1176 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X3, TYPE_FLOAT);
1177 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X4, TYPE_FLOAT);
1178 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X2, TYPE_FLOAT);
1179 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3, TYPE_FLOAT);
1180 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X4, TYPE_FLOAT);
1181 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X2, TYPE_FLOAT);
1182 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X3, TYPE_FLOAT);
1183 MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4, TYPE_FLOAT);
1186 MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_VEC2);
1187 MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_VEC2);
1188 MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_VEC2);
1189 MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_VEC3);
1190 MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_VEC3);
1191 MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_VEC3);
1192 MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_VEC4);
1193 MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_VEC4);
1194 MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_VEC4);
1197 MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT2);
1198 MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT2X3);
1199 MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT2X4);
1200 MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT3X2);
1201 MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT3);
1202 MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT3X4);
1203 MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT4X2);
1204 MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT4X3);
1205 MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT4);
1208 MAKE_CWISE_OPS(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT2);
1209 MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT2);
1210 MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT3X2);
1211 MAKE_MUL_OP(TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT4X2);
1213 MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT2X3);
1214 MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT2);
1215 MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT3X2);
1216 MAKE_MUL_OP(TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT4X2);
1218 MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT2X4);
1219 MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT2);
1220 MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT3X2);
1221 MAKE_MUL_OP(TYPE_FLOAT_MAT2X4, TYPE_FLOAT_MAT4X2);
1223 MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT3X2);
1224 MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT2X3);
1225 MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT3);
1226 MAKE_MUL_OP(TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT4X3);
1228 MAKE_CWISE_OPS(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT3);
1229 MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT2X3);
1230 MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT3);
1231 MAKE_MUL_OP(TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT4X3);
1233 MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT3X4);
1234 MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT2X3);
1235 MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT3);
1236 MAKE_MUL_OP(TYPE_FLOAT_MAT3X4, TYPE_FLOAT_MAT4X3);
1238 MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT4X2);
1239 MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT2X4);
1240 MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT3X4);
1241 MAKE_MUL_OP(TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT4);
1243 MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT4X3);
1244 MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT2X4);
1245 MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT3X4);
1246 MAKE_MUL_OP(TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT4);
1248 MAKE_CWISE_OPS(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT4);
1249 MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT2X4);
1250 MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT3X4);
1251 MAKE_MUL_OP(TYPE_FLOAT_MAT4, TYPE_FLOAT_MAT4);
1254 MAKE_VECVEC_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC2);
1255 MAKE_VECVEC_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3);
1256 MAKE_VECVEC_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC4);
1257 MAKE_VECVEC_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC2);
1258 MAKE_VECVEC_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC3);
1259 MAKE_VECVEC_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4);
1260 MAKE_VECVEC_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC2);
1261 MAKE_VECVEC_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC3);
1262 MAKE_VECVEC_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4);
1265 MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
1266 MAKE_UNARY_OP(TYPE_FLOAT_MAT2X3);
1267 MAKE_UNARY_OP(TYPE_FLOAT_MAT2X4);
1268 MAKE_UNARY_OP(TYPE_FLOAT_MAT3X2);
1269 MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
1270 MAKE_UNARY_OP(TYPE_FLOAT_MAT3X4);
1271 MAKE_UNARY_OP(TYPE_FLOAT_MAT4X2);
1272 MAKE_UNARY_OP(TYPE_FLOAT_MAT4X3);
1273 MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT4);
1276 MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
1277 MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X3);
1278 MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X4);
1279 MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X2);
1280 MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
1281 MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X4);
1282 MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X2);
1283 MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X3);
1284 MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT4);
1287 DE_ASSERT(DE_FALSE);
1291 #undef PACK_EVAL_CASE
1292 #undef MAKE_EVAL_CASE
1295 #undef MAKE_MAT_SCALAR_VEC_CASES
1296 #undef MAKE_MAT_MAT_CASES
1299 // Shader source format utilities.
1302 void writeVectorConstructor (std::ostream& str, const tcu::Vector<float, Size>& v)
1304 str << "vec" << Size << "(";
1305 for (int ndx = 0; ndx < Size; ndx++)
1309 str << de::floatToString(v[ndx], 1);
1314 template <int Cols, int Rows>
1315 void writeMatrixConstructor (std::ostream& str, const tcu::Matrix<float, Rows, Cols>& m)
1318 str << "mat" << Cols;
1320 str << "mat" << Cols << "x" << Rows;
1323 for (int colNdx = 0; colNdx < Cols; colNdx++)
1325 for (int rowNdx = 0; rowNdx < Rows; rowNdx++)
1327 if (rowNdx > 0 || colNdx > 0)
1329 str << de::floatToString(m(rowNdx, colNdx), 1);
1335 } // MatrixCaseUtils
1337 using namespace MatrixCaseUtils;
1339 class MatrixShaderEvaluator : public ShaderEvaluator
1342 MatrixShaderEvaluator (MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1);
1344 virtual void evaluate (ShaderEvalContext& evalCtx) const;
1347 MatrixShaderEvalFunc m_matEvalFunc;
1348 InputType m_inType0;
1349 InputType m_inType1;
1352 MatrixShaderEvaluator::MatrixShaderEvaluator (MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1)
1353 : m_matEvalFunc (evalFunc)
1354 , m_inType0 (inType0)
1355 , m_inType1 (inType1)
1359 void MatrixShaderEvaluator::evaluate (ShaderEvalContext& evalCtx) const
1361 m_matEvalFunc(evalCtx, m_inType0, m_inType1);
1365 BaseAttributeType getAttributeType(const glu::DataType dataType)
1369 case TYPE_FLOAT_MAT2: return MAT2;
1370 case TYPE_FLOAT_MAT2X3: return MAT2x3;
1371 case TYPE_FLOAT_MAT2X4: return MAT2x4;
1372 case TYPE_FLOAT_MAT3X2: return MAT3x2;
1373 case TYPE_FLOAT_MAT3: return MAT3;
1374 case TYPE_FLOAT_MAT3X4: return MAT3x4;
1375 case TYPE_FLOAT_MAT4X2: return MAT4x2;
1376 case TYPE_FLOAT_MAT4X3: return MAT4x3;
1377 case TYPE_FLOAT_MAT4: return MAT4;
1379 TCU_THROW(InternalError, "Not supported");
1384 // ShaderMatrixInstance
1386 class ShaderMatrixInstance : public ShaderRenderCaseInstance
1389 ShaderMatrixInstance (Context& context,
1391 const ShaderEvaluator& evaluator,
1392 const ShaderInput in0,
1393 const ShaderInput in1,
1394 const MatrixOp m_op);
1395 virtual ~ShaderMatrixInstance (void);
1398 virtual void setupUniforms (const tcu::Vec4&);
1401 void addMatrixUniform (deUint32 bindingLocation, DataType dataType, const float* dataPtr);
1403 const ShaderInput m_in0;
1404 const ShaderInput m_in1;
1405 const MatrixOp m_op;
1408 ShaderMatrixInstance::ShaderMatrixInstance (Context& context,
1410 const ShaderEvaluator& evaluator,
1411 const ShaderInput in0,
1412 const ShaderInput in1,
1414 : ShaderRenderCaseInstance (context, isVertex, evaluator, DE_NULL, DE_NULL, IMAGE_BACKING_MODE_REGULAR, isVertex && op == OP_INVERSE ? 64 : GRID_SIZE_DEFAULTS)
1419 m_userAttribTransforms.resize(4);
1420 for (int attribNdx = 0; attribNdx < 4; attribNdx++)
1422 m_userAttribTransforms[attribNdx] = Mat4(0.0f);
1423 m_userAttribTransforms[attribNdx]( 0, 3) = 0.2f; // !< prevent matrix*vec from going into zero (assuming vec.w != 0)
1424 m_userAttribTransforms[attribNdx]( 1, 3) = 0.1f; // !<
1425 m_userAttribTransforms[attribNdx]( 2, 3) = 0.4f + 0.15f * float(attribNdx); // !<
1426 m_userAttribTransforms[attribNdx]( 3, 3) = 0.7f; // !<
1427 m_userAttribTransforms[attribNdx]((0 + attribNdx) % 4, 0) = 1.0f;
1428 m_userAttribTransforms[attribNdx]((1 + attribNdx) % 4, 1) = 1.0f;
1429 m_userAttribTransforms[attribNdx]((2 + attribNdx) % 4, 2) = 1.0f;
1430 m_userAttribTransforms[attribNdx]((3 + attribNdx) % 4, 3) = 1.0f;
1433 // prevent bad reference cases such as black result images by fine-tuning used matrices
1434 if (getOperationTestMatrixType(m_op) != TESTMATRIXTYPE_DEFAULT)
1436 for (int attribNdx = 0; attribNdx < 4; attribNdx++)
1438 for (int row = 0; row < 4; row++)
1439 for (int col = 0; col < 4; col++)
1441 switch (getOperationTestMatrixType(m_op))
1443 case TESTMATRIXTYPE_NEGATED:
1444 m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col);
1446 case TESTMATRIXTYPE_INCREMENTED:
1447 m_userAttribTransforms[attribNdx](row, col) += 0.3f;
1449 case TESTMATRIXTYPE_DECREMENTED:
1450 m_userAttribTransforms[attribNdx](row, col) -= 0.3f;
1452 case TESTMATRIXTYPE_NEGATED_INCREMENTED:
1453 m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col) + 0.3f;
1455 case TESTMATRIXTYPE_INCREMENTED_LESS:
1456 m_userAttribTransforms[attribNdx](row, col) -= 0.1f;
1460 DE_ASSERT(DE_FALSE);
1467 int numInputs = isOperationBinary(m_op) ? 2 : 1;
1469 for (int inNdx = 0; inNdx < numInputs; inNdx++)
1471 const ShaderInput& in = inNdx > 0 ? m_in1 : m_in0;
1473 if (in.inputType == INPUTTYPE_DYNAMIC && isDataTypeMatrix(in.dataType))
1475 useAttribute(4u + inNdx, getAttributeType(in.dataType));
1481 ShaderMatrixInstance::~ShaderMatrixInstance (void)
1485 void ShaderMatrixInstance::addMatrixUniform(deUint32 bindingLocation, DataType dataType, const float *dataPtr)
1488 const size_t matrixSize = sizeof(float) * 4 * 4;
1492 case TYPE_FLOAT_MAT2:
1494 Mat2 matrix = Mat2(dataPtr);
1495 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1496 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1499 case TYPE_FLOAT_MAT2X3:
1501 Mat2x3 matrix = Mat2x3(dataPtr);
1502 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1503 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1506 case TYPE_FLOAT_MAT2X4:
1508 Mat2x4 matrix = Mat2x4(dataPtr);
1509 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1510 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1513 case TYPE_FLOAT_MAT3X2:
1515 Mat3x2 matrix = Mat3x2(dataPtr);
1516 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1517 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1518 result.setColumn(2, matrix.getColumn(2).toWidth<4>());
1521 case TYPE_FLOAT_MAT3:
1523 Mat3 matrix = Mat3(dataPtr);
1524 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1525 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1526 result.setColumn(2, matrix.getColumn(2).toWidth<4>());
1529 case TYPE_FLOAT_MAT3X4:
1531 Mat3x4 matrix = Mat3x4(dataPtr);
1532 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1533 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1534 result.setColumn(2, matrix.getColumn(2).toWidth<4>());
1537 case TYPE_FLOAT_MAT4X2:
1539 Mat4x2 matrix = Mat4x2(dataPtr);
1540 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1541 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1542 result.setColumn(2, matrix.getColumn(2).toWidth<4>());
1543 result.setColumn(3, matrix.getColumn(3).toWidth<4>());
1546 case TYPE_FLOAT_MAT4X3:
1548 Mat4x3 matrix = Mat4x3(dataPtr);
1549 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1550 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1551 result.setColumn(2, matrix.getColumn(2).toWidth<4>());
1552 result.setColumn(3, matrix.getColumn(3).toWidth<4>());
1555 case TYPE_FLOAT_MAT4:
1557 Mat4 matrix = Mat4(dataPtr);
1558 result.setColumn(0, matrix.getColumn(0).toWidth<4>());
1559 result.setColumn(1, matrix.getColumn(1).toWidth<4>());
1560 result.setColumn(2, matrix.getColumn(2).toWidth<4>());
1561 result.setColumn(3, matrix.getColumn(3).toWidth<4>());
1569 addUniform(bindingLocation, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, matrixSize, result.getColumnMajorData().getPtr());
1572 void ShaderMatrixInstance::setupUniforms (const tcu::Vec4&)
1574 const int numInputs = isOperationBinary(m_op) ? 2 : 1;
1575 deUint32 uniformBinding = 0;
1577 for (int inNdx = 0; inNdx < numInputs; inNdx++)
1579 const ShaderInput& in = inNdx > 0 ? m_in1 : m_in0;
1581 if (in.inputType == INPUTTYPE_UNIFORM)
1583 switch (in.dataType)
1585 case TYPE_FLOAT: addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(float), &s_constInFloat[inNdx]); break;
1586 case TYPE_FLOAT_VEC2: addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, s_constInVec2[inNdx]); break;
1587 case TYPE_FLOAT_VEC3: addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, s_constInVec3[inNdx]); break;
1588 case TYPE_FLOAT_VEC4: addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, s_constInVec4[inNdx]); break;
1589 // \note GLES3 supports transpose in matrix upload.
1590 case TYPE_FLOAT_MAT2: addMatrixUniform(uniformBinding, in.dataType, s_constInMat2x2[inNdx]); break;
1591 case TYPE_FLOAT_MAT2X3: addMatrixUniform(uniformBinding, in.dataType, s_constInMat2x3[inNdx]); break;
1592 case TYPE_FLOAT_MAT2X4: addMatrixUniform(uniformBinding, in.dataType, s_constInMat2x4[inNdx]); break;
1593 case TYPE_FLOAT_MAT3X2: addMatrixUniform(uniformBinding, in.dataType, s_constInMat3x2[inNdx]); break;
1594 case TYPE_FLOAT_MAT3: addMatrixUniform(uniformBinding, in.dataType, s_constInMat3x3[inNdx]); break;
1595 case TYPE_FLOAT_MAT3X4: addMatrixUniform(uniformBinding, in.dataType, s_constInMat3x4[inNdx]); break;
1596 case TYPE_FLOAT_MAT4X2: addMatrixUniform(uniformBinding, in.dataType, s_constInMat4x2[inNdx]); break;
1597 case TYPE_FLOAT_MAT4X3: addMatrixUniform(uniformBinding, in.dataType, s_constInMat4x3[inNdx]); break;
1598 case TYPE_FLOAT_MAT4: addMatrixUniform(uniformBinding, in.dataType, s_constInMat4x4[inNdx]); break;
1609 class ShaderMatrixCase : public ShaderRenderCase
1612 ShaderMatrixCase (tcu::TestContext& testCtx,
1613 const std::string& name,
1614 const std::string& desc,
1615 const ShaderInput& in0,
1616 const ShaderInput& in1,
1619 ~ShaderMatrixCase (void);
1621 virtual TestInstance* createInstance (Context& context) const;
1624 void setupShader (void);
1625 std::string genGLSLMatToVec3Reduction (const glu::DataType& matType, const char* varName);
1628 const ShaderInput m_in0;
1629 const ShaderInput m_in1;
1630 const MatrixOp m_op;
1633 ShaderMatrixCase::ShaderMatrixCase (tcu::TestContext& testCtx,
1634 const std::string& name,
1635 const std::string& desc,
1636 const ShaderInput& in0,
1637 const ShaderInput& in1,
1640 : ShaderRenderCase (testCtx,
1644 new MatrixShaderEvaluator(getEvalFunc(in0, in1, op), in0.inputType, in1.inputType),
1645 DE_NULL /* uniform setup */,
1646 DE_NULL /* attribute setup */)
1654 ShaderMatrixCase::~ShaderMatrixCase (void)
1658 TestInstance* ShaderMatrixCase::createInstance (Context& context) const
1660 return new ShaderMatrixInstance(context, m_isVertexCase, *m_evaluator, m_in0, m_in1, m_op);
1663 void ShaderMatrixCase::setupShader (void)
1665 std::ostringstream vtx;
1666 std::ostringstream frag;
1667 std::ostringstream& op = m_isVertexCase ? vtx : frag;
1669 bool isInDynMat0 = isDataTypeMatrix(m_in0.dataType) && m_in0.inputType == INPUTTYPE_DYNAMIC;
1670 bool isInDynMat1 = isDataTypeMatrix(m_in1.dataType) && m_in1.inputType == INPUTTYPE_DYNAMIC;
1673 DataType resultType = TYPE_LAST;
1674 Precision resultPrec = m_in0.precision;
1675 vector<string> passVars;
1676 int numInputs = (isOperationBinary(m_op)) ? (2) : (1);
1678 std::string operationValue0;
1679 std::string operationValue1;
1681 DE_ASSERT(!isInDynMat0 || !isInDynMat1); // Only single dynamic matrix input is allowed.
1682 DE_UNREF(isInDynMat0 && isInDynMat1);
1684 // Compute result type.
1685 if (m_op == OP_MUL && isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
1687 resultType = getDataTypeMatrix(getDataTypeMatrixNumColumns(m_in1.dataType), getDataTypeMatrixNumRows(m_in0.dataType));
1689 else if (m_op == OP_OUTER_PRODUCT)
1691 resultType = getDataTypeMatrix(getDataTypeScalarSize(m_in1.dataType), getDataTypeScalarSize(m_in0.dataType));
1693 else if (m_op == OP_TRANSPOSE)
1695 resultType = getDataTypeMatrix(getDataTypeMatrixNumRows(m_in0.dataType), getDataTypeMatrixNumColumns(m_in0.dataType));
1697 else if (m_op == OP_INVERSE)
1699 resultType = m_in0.dataType;
1701 else if (m_op == OP_DETERMINANT)
1703 resultType = TYPE_FLOAT;
1705 else if (getOperationType(m_op) == OPERATIONTYPE_UNARY_PREFIX_OPERATOR ||
1706 getOperationType(m_op) == OPERATIONTYPE_UNARY_POSTFIX_OPERATOR)
1708 resultType = m_in0.dataType;
1710 else if (isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
1712 DE_ASSERT(m_in0.dataType == m_in1.dataType);
1713 resultType = m_in0.dataType;
1715 else if (isDataTypeMatrix(m_in0.dataType) || isDataTypeMatrix(m_in1.dataType))
1717 int matNdx = isDataTypeMatrix(m_in0.dataType) ? 0 : 1;
1718 DataType matrixType = matNdx == 0 ? m_in0.dataType : m_in1.dataType;
1719 DataType otherType = matNdx == 0 ? m_in1.dataType : m_in0.dataType;
1721 if (otherType == TYPE_FLOAT)
1722 resultType = matrixType;
1725 DE_ASSERT(isDataTypeVector(otherType));
1726 resultType = getDataTypeFloatVec(matNdx == 0 ? getDataTypeMatrixNumRows(matrixType) : getDataTypeMatrixNumColumns(matrixType));
1731 DE_ASSERT(DE_FALSE);
1734 static const std::string header =
1735 "#version 310 es\n";
1740 vtx << "layout(location = 0) in highp vec4 a_position;\n";
1741 frag << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
1744 vtx << "layout(location = 0) out mediump vec4 v_color;\n";
1745 frag << "layout(location = 0) in mediump vec4 v_color;\n";
1748 // Input declarations.
1749 deUint32 uniformBinding = 0;
1750 deUint32 padding = 0;
1751 for (int inNdx = 0; inNdx < numInputs; inNdx++)
1753 const ShaderInput& in = inNdx > 0 ? m_in1 : m_in0;
1754 const char* precName = getPrecisionName(in.precision);
1755 const char* typeName = getDataTypeName(in.dataType);
1756 string& inValue = inNdx > 0 ? inValue1 : inValue0;
1758 if (in.inputType == INPUTTYPE_DYNAMIC)
1760 if (isDataTypeMatrix(in.dataType))
1762 vtx << "layout(location = " << 4 + inNdx + padding << ") in " << precName << " " << typeName << " a_";
1764 vtx << typeName << ";\n";
1765 if (!m_isVertexCase)
1767 vtx << "layout(location = " << 1 + inNdx + padding << ") out " << precName << " " << typeName << " v_" << typeName << ";\n";
1768 frag << "layout(location = " << 1 + inNdx + padding << ") in " << precName << " " << typeName << " v_" << typeName << ";\n";
1769 passVars.push_back(typeName);
1772 inValue = string(m_isVertexCase ? "a_" : "v_") + getDataTypeName(in.dataType);
1773 padding += getDataTypeMatrixNumColumns(in.dataType);
1777 // a_coords, v_coords
1778 vtx << "layout(location = 1) in " << precName << " " << typeName << " a_coords;\n";
1779 if (!m_isVertexCase)
1781 vtx << "layout(location = " << 1 + padding << ") out " << precName << " " << typeName << " v_coords;\n";
1782 frag << "layout(location = " << 1 + padding << ") in " << precName << " " << typeName << " v_coords;\n";
1783 passVars.push_back("coords");
1786 inValue = m_isVertexCase ? "a_coords" : "v_coords";
1789 else if (in.inputType == INPUTTYPE_UNIFORM)
1791 op << "layout(std140, set = 0, binding = " << uniformBinding++ << ") uniform buffer"<< inNdx <<" { " << precName << " " << typeName << " u_in" << inNdx << "; };\n";
1792 inValue = string("u_in") + de::toString(inNdx);
1794 else if (in.inputType == INPUTTYPE_CONST)
1796 op << "const " << precName << " " << typeName << " in" << inNdx << " = ";
1798 // Generate declaration.
1799 switch (in.dataType)
1801 case TYPE_FLOAT: op << de::floatToString(s_constInFloat[inNdx], 1); break;
1802 case TYPE_FLOAT_VEC2: writeVectorConstructor<2>(op, s_constInVec2[inNdx]); break;
1803 case TYPE_FLOAT_VEC3: writeVectorConstructor<3>(op, s_constInVec3[inNdx]); break;
1804 case TYPE_FLOAT_VEC4: writeVectorConstructor<4>(op, s_constInVec4[inNdx]); break;
1805 case TYPE_FLOAT_MAT2: writeMatrixConstructor<2, 2>(op, Mat2(s_constInMat2x2[inNdx])); break;
1806 case TYPE_FLOAT_MAT2X3: writeMatrixConstructor<2, 3>(op, Mat2x3(s_constInMat2x3[inNdx])); break;
1807 case TYPE_FLOAT_MAT2X4: writeMatrixConstructor<2, 4>(op, Mat2x4(s_constInMat2x4[inNdx])); break;
1808 case TYPE_FLOAT_MAT3X2: writeMatrixConstructor<3, 2>(op, Mat3x2(s_constInMat3x2[inNdx])); break;
1809 case TYPE_FLOAT_MAT3: writeMatrixConstructor<3, 3>(op, Mat3(s_constInMat3x3[inNdx])); break;
1810 case TYPE_FLOAT_MAT3X4: writeMatrixConstructor<3, 4>(op, Mat3x4(s_constInMat3x4[inNdx])); break;
1811 case TYPE_FLOAT_MAT4X2: writeMatrixConstructor<4, 2>(op, Mat4x2(s_constInMat4x2[inNdx])); break;
1812 case TYPE_FLOAT_MAT4X3: writeMatrixConstructor<4, 3>(op, Mat4x3(s_constInMat4x3[inNdx])); break;
1813 case TYPE_FLOAT_MAT4: writeMatrixConstructor<4, 4>(op, Mat4(s_constInMat4x4[inNdx])); break;
1816 DE_ASSERT(DE_FALSE);
1821 inValue = string("in") + de::toString(inNdx);
1826 << "void main (void)\n"
1828 << " gl_Position = a_position;\n";
1830 << "void main (void)\n"
1834 frag << " dEQP_FragColor = v_color;\n";
1837 for (vector<string>::const_iterator copyIter = passVars.begin(); copyIter != passVars.end(); copyIter++)
1838 vtx << " v_" << *copyIter << " = " << "a_" << *copyIter << ";\n";
1843 switch (getOperationNature(m_op))
1845 case OPERATIONNATURE_PURE:
1846 DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
1848 operationValue0 = inValue0;
1849 operationValue1 = inValue1;
1852 case OPERATIONNATURE_MUTATING:
1853 DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
1855 op << " " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " tmpValue = " << inValue0 << ";\n";
1857 operationValue0 = "tmpValue";
1858 operationValue1 = inValue1;
1861 case OPERATIONNATURE_ASSIGNMENT:
1862 DE_ASSERT(getOperationType(m_op) == OPERATIONTYPE_ASSIGNMENT);
1864 operationValue0 = inValue0;
1865 operationValue1 = inValue1;
1869 DE_ASSERT(DE_FALSE);
1872 switch (getOperationType(m_op))
1874 case OPERATIONTYPE_BINARY_OPERATOR:
1875 op << " " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << " " << getOperationName(m_op) << " " << operationValue1 << ";\n";
1878 case OPERATIONTYPE_UNARY_PREFIX_OPERATOR:
1879 op << " " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << operationValue0 << ";\n";
1882 case OPERATIONTYPE_UNARY_POSTFIX_OPERATOR:
1883 op << " " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << getOperationName(m_op) << ";\n";
1886 case OPERATIONTYPE_BINARY_FUNCTION:
1887 op << " " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << "(" << operationValue0 << ", " << operationValue1 << ");\n";
1890 case OPERATIONTYPE_UNARY_FUNCTION:
1891 op << " " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << "(" << operationValue0 << ");\n";
1894 case OPERATIONTYPE_ASSIGNMENT:
1895 op << " " << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << ";\n";
1896 op << " res " << getOperationName(m_op) << " " << operationValue1 << ";\n";
1900 DE_ASSERT(DE_FALSE);
1903 // Reduction to vec3 (rgb). Check the used value too if it was modified
1904 op << " " << (m_isVertexCase ? "v_color" : "dEQP_FragColor") << " = ";
1906 if (isOperationValueModifying(m_op))
1907 op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0) + vec4(" << genGLSLMatToVec3Reduction(resultType, "tmpValue") << ", 0.0);\n";
1909 op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0);\n";
1914 m_vertShaderSource = vtx.str();
1915 m_fragShaderSource = frag.str();
1918 std::string ShaderMatrixCase::genGLSLMatToVec3Reduction (const glu::DataType& matType, const char* varName)
1920 std::ostringstream op;
1924 case TYPE_FLOAT: op << varName << ", " << varName << ", " << varName << ""; break;
1925 case TYPE_FLOAT_VEC2: op << varName << ".x, " << varName << ".y, " << varName << ".x"; break;
1926 case TYPE_FLOAT_VEC3: op << varName << ""; break;
1927 case TYPE_FLOAT_VEC4: op << varName << ".x, " << varName << ".y, " << varName << ".z+" << varName << ".w"; break;
1928 case TYPE_FLOAT_MAT2: op << varName << "[0][0], " << varName << "[1][0], " << varName << "[0][1]+" << varName << "[1][1]"; break;
1929 case TYPE_FLOAT_MAT2X3: op << varName << "[0] + " << varName << "[1]"; break;
1930 case TYPE_FLOAT_MAT2X4: op << varName << "[0].xyz + " << varName << "[1].yzw"; break;
1931 case TYPE_FLOAT_MAT3X2: op << varName << "[0][0]+" << varName << "[0][1], " << varName << "[1][0]+" << varName << "[1][1], " << varName << "[2][0]+" << varName << "[2][1]"; break;
1932 case TYPE_FLOAT_MAT3: op << varName << "[0] + " << varName << "[1] + " << varName << "[2]"; break;
1933 case TYPE_FLOAT_MAT3X4: op << varName << "[0].xyz + " << varName << "[1].yzw + " << varName << "[2].zwx"; break;
1934 case TYPE_FLOAT_MAT4X2: op << varName << "[0][0]+" << varName << "[0][1]+" << varName << "[3][0], " << varName << "[1][0]+" << varName << "[1][1]+" << varName << "[3][1], " << varName << "[2][0]+" << varName << "[2][1]"; break;
1935 case TYPE_FLOAT_MAT4X3: op << varName << "[0] + " << varName << "[1] + " << varName << "[2] + " << varName << "[3]"; break;
1936 case TYPE_FLOAT_MAT4: op << varName << "[0].xyz+" << varName << "[1].yzw+" << varName << "[2].zwx+" << varName << "[3].wxy"; break;
1939 DE_ASSERT(DE_FALSE);
1945 class ShaderMatrixTests : public tcu::TestCaseGroup
1948 ShaderMatrixTests (tcu::TestContext& testCtx);
1949 virtual ~ShaderMatrixTests (void);
1951 virtual void init (void);
1954 ShaderMatrixTests (const ShaderMatrixTests&); // not allowed!
1955 ShaderMatrixTests& operator= (const ShaderMatrixTests&); // not allowed!
1958 ShaderMatrixTests::ShaderMatrixTests (tcu::TestContext& testCtx)
1959 : TestCaseGroup(testCtx, "matrix", "Matrix Tests")
1963 ShaderMatrixTests::~ShaderMatrixTests (void)
1967 void ShaderMatrixTests::init (void)
1974 const bool extendedInputTypeCases; // !< test with const and uniform types too
1975 const bool createInputTypeGroup; // !< create group for input types
1978 { "add", "Matrix addition tests", OP_ADD, true, true },
1979 { "sub", "Matrix subtraction tests", OP_SUB, true, true },
1980 { "mul", "Matrix multiplication tests", OP_MUL, true, true },
1981 { "div", "Matrix division tests", OP_DIV, true, true },
1982 { "matrixcompmult", "Matrix component-wise multiplication tests", OP_COMP_MUL, false, true },
1983 { "outerproduct", "Matrix outerProduct() tests", OP_OUTER_PRODUCT, false, true },
1984 { "transpose", "Matrix transpose() tests", OP_TRANSPOSE, false, true },
1985 { "determinant", "Matrix determinant() tests", OP_DETERMINANT, false, true },
1986 { "inverse", "Matrix inverse() tests", OP_INVERSE, false, true },
1987 { "unary_addition", "Matrix unary addition tests", OP_UNARY_PLUS, false, false },
1988 { "negation", "Matrix negation tests", OP_NEGATION, false, false },
1989 { "pre_increment", "Matrix prefix increment tests", OP_PRE_INCREMENT, false, false },
1990 { "pre_decrement", "Matrix prefix decrement tests", OP_PRE_DECREMENT, false, false },
1991 { "post_increment", "Matrix postfix increment tests", OP_POST_INCREMENT, false, false },
1992 { "post_decrement", "Matrix postfix decrement tests", OP_POST_DECREMENT, false, false },
1993 { "add_assign", "Matrix add into tests", OP_ADD_INTO, false, false },
1994 { "sub_assign", "Matrix subtract from tests", OP_SUBTRACT_FROM, false, false },
1995 { "mul_assign", "Matrix multiply into tests", OP_MULTIPLY_INTO, false, false },
1996 { "div_assign", "Matrix divide into tests", OP_DIVIDE_INTO, false, false },
1999 struct InputTypeSpec
2003 const InputType type;
2005 static const InputTypeSpec extendedInputTypes[] =
2007 { "const", "Constant matrix input", INPUTTYPE_CONST },
2008 { "uniform", "Uniform matrix input", INPUTTYPE_UNIFORM },
2009 { "dynamic", "Dynamic matrix input", INPUTTYPE_DYNAMIC }
2011 static const InputTypeSpec reducedInputTypes[] =
2013 { "dynamic", "Dynamic matrix input", INPUTTYPE_DYNAMIC }
2016 static const DataType matrixTypes[] =
2029 static const Precision precisions[] =
2035 for (int opNdx = 0; opNdx < DE_LENGTH_OF_ARRAY(ops); opNdx++)
2037 const InputTypeSpec* inTypeList = (ops[opNdx].extendedInputTypeCases) ? (extendedInputTypes) : (reducedInputTypes);
2038 const int inTypeListSize = (ops[opNdx].extendedInputTypeCases) ? (DE_LENGTH_OF_ARRAY(extendedInputTypes)) : (DE_LENGTH_OF_ARRAY(reducedInputTypes));
2039 const MatrixOp op = ops[opNdx].op;
2040 tcu::TestCaseGroup* opGroup = new tcu::TestCaseGroup(m_testCtx, ops[opNdx].name, ops[opNdx].desc);
2044 for (int inTypeNdx = 0; inTypeNdx < inTypeListSize; inTypeNdx++)
2046 const InputType inputType = inTypeList[inTypeNdx].type;
2047 tcu::TestCaseGroup* inGroup;
2049 if (ops[opNdx].createInputTypeGroup)
2051 inGroup = new tcu::TestCaseGroup(m_testCtx, inTypeList[inTypeNdx].name, inTypeList[inTypeNdx].desc);
2052 opGroup->addChild(inGroup);
2057 for (int matTypeNdx = 0; matTypeNdx < DE_LENGTH_OF_ARRAY(matrixTypes); matTypeNdx++)
2059 DataType matType = matrixTypes[matTypeNdx];
2060 int numCols = getDataTypeMatrixNumColumns(matType);
2061 int numRows = getDataTypeMatrixNumRows(matType);
2062 const char* matTypeName = getDataTypeName(matType);
2064 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++)
2066 Precision precision = precisions[precNdx];
2067 const char* precName = getPrecisionName(precision);
2068 string baseName = string(precName) + "_" + matTypeName + "_";
2069 ShaderInput matIn (inputType, matType, precision);
2071 if (isOperationMatrixScalar(op))
2073 // Matrix-scalar \note For div cases we use uniform input.
2074 ShaderInput scalarIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, TYPE_FLOAT, precision);
2075 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(), "Matrix-scalar case", matIn, scalarIn, op, true));
2076 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(), "Matrix-scalar case", matIn, scalarIn, op, false));
2079 if (isOperationMatrixVector(op))
2082 DataType colVecType = getDataTypeFloatVec(numCols);
2083 ShaderInput colVecIn (op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, colVecType, precision);
2085 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(colVecType) + "_vertex").c_str(), "Matrix-vector case", matIn, colVecIn, op, true));
2086 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(colVecType) + "_fragment").c_str(), "Matrix-vector case", matIn, colVecIn, op, false));
2089 DataType rowVecType = getDataTypeFloatVec(numRows);
2090 ShaderInput rowVecIn (op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, rowVecType, precision);
2091 string vecMatName = string(precName) + "_" + getDataTypeName(rowVecType) + "_" + matTypeName;
2093 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (vecMatName + "_vertex").c_str(), "Vector-matrix case", rowVecIn, matIn, op, true));
2094 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (vecMatName + "_fragment").c_str(), "Vector-matrix case", rowVecIn, matIn, op, false));
2097 if (isOperationArithmeticMatrixMatrix(op))
2099 // Arithmetic matrix-matrix multiplication.
2100 for (int otherCols = 2; otherCols <= 4; otherCols++)
2102 ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, getDataTypeMatrix(otherCols, numCols /* rows */), precision);
2103 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(otherMatIn.dataType) + "_vertex").c_str(), "Matrix-matrix case", matIn, otherMatIn, op, true));
2104 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(otherMatIn.dataType) + "_fragment").c_str(), "Matrix-matrix case", matIn, otherMatIn, op, false));
2107 else if (isOperationComponentwiseMatrixMatrix(op))
2110 ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType, precision);
2111 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + matTypeName + "_vertex").c_str(), "Matrix-matrix case", matIn, otherMatIn, op, true));
2112 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + matTypeName + "_fragment").c_str(), "Matrix-matrix case", matIn, otherMatIn, op, false));
2115 if (isOperationVectorVector(op))
2117 ShaderInput vec1In(inputType, getDataTypeFloatVec(numRows), precision);
2118 ShaderInput vec2In((inputType == INPUTTYPE_DYNAMIC) ? (INPUTTYPE_UNIFORM) : (inputType), getDataTypeFloatVec(numCols), precision);
2120 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(), "Vector-vector case", vec1In, vec2In, op, true));
2121 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(), "Vector-vector case", vec1In, vec2In, op, false));
2124 if ((isOperationUnaryAnyMatrix(op)) ||
2125 (isOperationUnarySymmetricMatrix(op) && numCols == numRows))
2127 ShaderInput voidInput(INPUTTYPE_LAST, TYPE_LAST, PRECISION_LAST);
2128 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(), "Matrix case", matIn, voidInput, op, true));
2129 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(), "Matrix case", matIn, voidInput, op, false));
2132 if ((isOperationAssignmentAnyMatrix(op)) ||
2133 (isOperationAssignmentSymmetricMatrix(op) && numCols == numRows))
2135 ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType, precision);
2136 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(), "Matrix assignment case", matIn, otherMatIn, op, true));
2137 inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(), "Matrix assignment case", matIn, otherMatIn, op, false));
2147 tcu::TestCaseGroup* createMatrixTests (tcu::TestContext& testCtx)
2149 return new ShaderMatrixTests(testCtx);