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