1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2016 Google Inc. 6 * Copyright (c) 2016 The Khronos Group Inc. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 */ /*! 21 * \file 22 * \brief Shader indexing (arrays, vector, matrices) tests. 23 */ /*-------------------------------------------------------------------*/ 24 25#include "glcShaderIndexingTests.hpp" 26#include "glcShaderRenderCase.hpp" 27#include "gluShaderUtil.hpp" 28#include "glwEnums.hpp" 29#include "glwFunctions.hpp" 30#include "tcuStringTemplate.hpp" 31 32#include "deInt32.h" 33#include "deMemory.h" 34 35#include <map> 36 37using namespace std; 38using namespace tcu; 39using namespace glu; 40using namespace deqp; 41 42namespace deqp 43{ 44 45enum IndexAccessType 46{ 47 INDEXACCESS_STATIC = 0, 48 INDEXACCESS_DYNAMIC, 49 INDEXACCESS_STATIC_LOOP, 50 INDEXACCESS_DYNAMIC_LOOP, 51 52 INDEXACCESS_LAST 53}; 54 55static const char* getIndexAccessTypeName(IndexAccessType accessType) 56{ 57 static const char* s_names[INDEXACCESS_LAST] = { "static", "dynamic", "static_loop", "dynamic_loop" }; 58 59 DE_ASSERT(deInBounds32((int)accessType, 0, INDEXACCESS_LAST)); 60 return s_names[(int)accessType]; 61} 62 63enum VectorAccessType 64{ 65 DIRECT = 0, 66 COMPONENT, 67 SUBSCRIPT_STATIC, 68 SUBSCRIPT_DYNAMIC, 69 SUBSCRIPT_STATIC_LOOP, 70 SUBSCRIPT_DYNAMIC_LOOP, 71 72 VECTORACCESS_LAST 73}; 74 75static const char* getVectorAccessTypeName(VectorAccessType accessType) 76{ 77 static const char* s_names[VECTORACCESS_LAST] = { "direct", 78 "component", 79 "static_subscript", 80 "dynamic_subscript", 81 "static_loop_subscript", 82 "dynamic_loop_subscript" }; 83 84 DE_ASSERT(deInBounds32((int)accessType, 0, VECTORACCESS_LAST)); 85 return s_names[(int)accessType]; 86} 87 88void evalArrayCoordsFloat(ShaderEvalContext& c) 89{ 90 c.color.x() = 1.875f * c.coords.x(); 91} 92void evalArrayCoordsVec2(ShaderEvalContext& c) 93{ 94 c.color.xy() = 1.875f * c.coords.swizzle(0, 1); 95} 96void evalArrayCoordsVec3(ShaderEvalContext& c) 97{ 98 c.color.xyz() = 1.875f * c.coords.swizzle(0, 1, 2); 99} 100void evalArrayCoordsVec4(ShaderEvalContext& c) 101{ 102 c.color = 1.875f * c.coords; 103} 104 105static ShaderEvalFunc getArrayCoordsEvalFunc(DataType dataType) 106{ 107 if (dataType == TYPE_FLOAT) 108 return evalArrayCoordsFloat; 109 else if (dataType == TYPE_FLOAT_VEC2) 110 return evalArrayCoordsVec2; 111 else if (dataType == TYPE_FLOAT_VEC3) 112 return evalArrayCoordsVec3; 113 else if (dataType == TYPE_FLOAT_VEC4) 114 return evalArrayCoordsVec4; 115 116 DE_ASSERT(DE_FALSE && "Invalid data type."); 117 return NULL; 118} 119 120void evalArrayUniformFloat(ShaderEvalContext& c) 121{ 122 c.color.x() = 1.875f * c.constCoords.x(); 123} 124void evalArrayUniformVec2(ShaderEvalContext& c) 125{ 126 c.color.xy() = 1.875f * c.constCoords.swizzle(0, 1); 127} 128void evalArrayUniformVec3(ShaderEvalContext& c) 129{ 130 c.color.xyz() = 1.875f * c.constCoords.swizzle(0, 1, 2); 131} 132void evalArrayUniformVec4(ShaderEvalContext& c) 133{ 134 c.color = 1.875f * c.constCoords; 135} 136 137static ShaderEvalFunc getArrayUniformEvalFunc(DataType dataType) 138{ 139 if (dataType == TYPE_FLOAT) 140 return evalArrayUniformFloat; 141 else if (dataType == TYPE_FLOAT_VEC2) 142 return evalArrayUniformVec2; 143 else if (dataType == TYPE_FLOAT_VEC3) 144 return evalArrayUniformVec3; 145 else if (dataType == TYPE_FLOAT_VEC4) 146 return evalArrayUniformVec4; 147 148 DE_ASSERT(DE_FALSE && "Invalid data type."); 149 return NULL; 150} 151 152// ShaderIndexingCase 153 154class ShaderIndexingCase : public ShaderRenderCase 155{ 156public: 157 ShaderIndexingCase(Context& context, const char* name, const char* description, bool isVertexCase, DataType varType, 158 ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource); 159 virtual ~ShaderIndexingCase(void); 160 161private: 162 ShaderIndexingCase(const ShaderIndexingCase&); // not allowed! 163 ShaderIndexingCase& operator=(const ShaderIndexingCase&); // not allowed! 164 165 virtual void setup(deUint32 programID); 166 virtual void setupUniforms(deUint32 programID, const Vec4& constCoords); 167 168 DataType m_varType; 169}; 170 171ShaderIndexingCase::ShaderIndexingCase(Context& context, const char* name, const char* description, bool isVertexCase, 172 DataType varType, ShaderEvalFunc evalFunc, const char* vertShaderSource, 173 const char* fragShaderSource) 174 : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, 175 description, isVertexCase, evalFunc) 176{ 177 m_varType = varType; 178 m_vertShaderSource = vertShaderSource; 179 m_fragShaderSource = fragShaderSource; 180} 181 182ShaderIndexingCase::~ShaderIndexingCase(void) 183{ 184} 185 186void ShaderIndexingCase::setup(deUint32 programID) 187{ 188 DE_UNREF(programID); 189} 190 191void ShaderIndexingCase::setupUniforms(deUint32 programID, const Vec4& constCoords) 192{ 193 const glw::Functions& gl = m_renderCtx.getFunctions(); 194 195 DE_UNREF(constCoords); 196 197 int arrLoc = gl.getUniformLocation(programID, "u_arr"); 198 if (arrLoc != -1) 199 { 200 //int scalarSize = getDataTypeScalarSize(m_varType); 201 if (m_varType == TYPE_FLOAT) 202 { 203 float arr[4]; 204 arr[0] = constCoords.x(); 205 arr[1] = constCoords.x() * 0.5f; 206 arr[2] = constCoords.x() * 0.25f; 207 arr[3] = constCoords.x() * 0.125f; 208 gl.uniform1fv(arrLoc, 4, &arr[0]); 209 } 210 else if (m_varType == TYPE_FLOAT_VEC2) 211 { 212 Vec2 arr[4]; 213 arr[0] = constCoords.swizzle(0, 1); 214 arr[1] = constCoords.swizzle(0, 1) * 0.5f; 215 arr[2] = constCoords.swizzle(0, 1) * 0.25f; 216 arr[3] = constCoords.swizzle(0, 1) * 0.125f; 217 gl.uniform2fv(arrLoc, 4, arr[0].getPtr()); 218 } 219 else if (m_varType == TYPE_FLOAT_VEC3) 220 { 221 Vec3 arr[4]; 222 arr[0] = constCoords.swizzle(0, 1, 2); 223 arr[1] = constCoords.swizzle(0, 1, 2) * 0.5f; 224 arr[2] = constCoords.swizzle(0, 1, 2) * 0.25f; 225 arr[3] = constCoords.swizzle(0, 1, 2) * 0.125f; 226 gl.uniform3fv(arrLoc, 4, arr[0].getPtr()); 227 } 228 else if (m_varType == TYPE_FLOAT_VEC4) 229 { 230 Vec4 arr[4]; 231 arr[0] = constCoords.swizzle(0, 1, 2, 3); 232 arr[1] = constCoords.swizzle(0, 1, 2, 3) * 0.5f; 233 arr[2] = constCoords.swizzle(0, 1, 2, 3) * 0.25f; 234 arr[3] = constCoords.swizzle(0, 1, 2, 3) * 0.125f; 235 gl.uniform4fv(arrLoc, 4, arr[0].getPtr()); 236 } 237 else 238 DE_TEST_ASSERT(false); 239 } 240} 241 242// Helpers. 243 244static ShaderIndexingCase* createVaryingArrayCase(Context& context, const char* caseName, const char* description, 245 glu::GLSLVersion glslVersion, DataType varType, 246 IndexAccessType vertAccess, IndexAccessType fragAccess) 247{ 248 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES || 249 glslVersion >= glu::GLSL_VERSION_330); 250 251 std::ostringstream vtx; 252 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 253 vtx << "in highp vec4 a_position;\n"; 254 vtx << "in highp vec4 a_coords;\n"; 255 if (vertAccess == INDEXACCESS_DYNAMIC) 256 vtx << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n"; 257 else if (vertAccess == INDEXACCESS_DYNAMIC_LOOP) 258 vtx << "uniform mediump int ui_four;\n"; 259 vtx << "out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n"; 260 vtx << "\n"; 261 vtx << "void main()\n"; 262 vtx << "{\n"; 263 vtx << " gl_Position = a_position;\n"; 264 if (vertAccess == INDEXACCESS_STATIC) 265 { 266 vtx << " var[0] = ${VAR_TYPE}(a_coords);\n"; 267 vtx << " var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n"; 268 vtx << " var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n"; 269 vtx << " var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n"; 270 } 271 else if (vertAccess == INDEXACCESS_DYNAMIC) 272 { 273 vtx << " var[ui_zero] = ${VAR_TYPE}(a_coords);\n"; 274 vtx << " var[ui_one] = ${VAR_TYPE}(a_coords) * 0.5;\n"; 275 vtx << " var[ui_two] = ${VAR_TYPE}(a_coords) * 0.25;\n"; 276 vtx << " var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n"; 277 } 278 else if (vertAccess == INDEXACCESS_STATIC_LOOP) 279 { 280 vtx << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n"; 281 vtx << " for (int i = 0; i < 4; i++)\n"; 282 vtx << " {\n"; 283 vtx << " var[i] = ${VAR_TYPE}(coords);\n"; 284 vtx << " coords = coords * 0.5;\n"; 285 vtx << " }\n"; 286 } 287 else 288 { 289 DE_ASSERT(vertAccess == INDEXACCESS_DYNAMIC_LOOP); 290 vtx << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n"; 291 vtx << " for (int i = 0; i < ui_four; i++)\n"; 292 vtx << " {\n"; 293 vtx << " var[i] = ${VAR_TYPE}(coords);\n"; 294 vtx << " coords = coords * 0.5;\n"; 295 vtx << " }\n"; 296 } 297 vtx << "}\n"; 298 299 std::ostringstream frag; 300 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 301 frag << "precision mediump int;\n"; 302 frag << "layout(location = 0) out mediump vec4 o_color;\n"; 303 if (fragAccess == INDEXACCESS_DYNAMIC) 304 frag << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n"; 305 else if (fragAccess == INDEXACCESS_DYNAMIC_LOOP) 306 frag << "uniform int ui_four;\n"; 307 frag << "in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n"; 308 frag << "\n"; 309 frag << "void main()\n"; 310 frag << "{\n"; 311 frag << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n"; 312 if (fragAccess == INDEXACCESS_STATIC) 313 { 314 frag << " res += var[0];\n"; 315 frag << " res += var[1];\n"; 316 frag << " res += var[2];\n"; 317 frag << " res += var[3];\n"; 318 } 319 else if (fragAccess == INDEXACCESS_DYNAMIC) 320 { 321 frag << " res += var[ui_zero];\n"; 322 frag << " res += var[ui_one];\n"; 323 frag << " res += var[ui_two];\n"; 324 frag << " res += var[ui_three];\n"; 325 } 326 else if (fragAccess == INDEXACCESS_STATIC_LOOP) 327 { 328 frag << " for (int i = 0; i < 4; i++)\n"; 329 frag << " res += var[i];\n"; 330 } 331 else 332 { 333 DE_ASSERT(fragAccess == INDEXACCESS_DYNAMIC_LOOP); 334 frag << " for (int i = 0; i < ui_four; i++)\n"; 335 frag << " res += var[i];\n"; 336 } 337 frag << " o_color = vec4(res${PADDING});\n"; 338 frag << "}\n"; 339 340 // Fill in shader templates. 341 map<string, string> params; 342 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType))); 343 params.insert(pair<string, string>("ARRAY_LEN", "4")); 344 params.insert(pair<string, string>("PRECISION", "mediump")); 345 346 if (varType == TYPE_FLOAT) 347 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0")); 348 else if (varType == TYPE_FLOAT_VEC2) 349 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0")); 350 else if (varType == TYPE_FLOAT_VEC3) 351 params.insert(pair<string, string>("PADDING", ", 1.0")); 352 else 353 params.insert(pair<string, string>("PADDING", "")); 354 355 StringTemplate vertTemplate(vtx.str().c_str()); 356 StringTemplate fragTemplate(frag.str().c_str()); 357 string vertexShaderSource = vertTemplate.specialize(params); 358 string fragmentShaderSource = fragTemplate.specialize(params); 359 360 ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType); 361 return new ShaderIndexingCase(context, caseName, description, true, varType, evalFunc, vertexShaderSource.c_str(), 362 fragmentShaderSource.c_str()); 363} 364 365static ShaderIndexingCase* createUniformArrayCase(Context& context, const char* caseName, const char* description, 366 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType, 367 IndexAccessType readAccess) 368{ 369 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES || 370 glslVersion >= glu::GLSL_VERSION_330); 371 372 std::ostringstream vtx; 373 std::ostringstream frag; 374 std::ostringstream& op = isVertexCase ? vtx : frag; 375 376 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 377 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 378 379 vtx << "in highp vec4 a_position;\n"; 380 vtx << "in highp vec4 a_coords;\n"; 381 frag << "layout(location = 0) out mediump vec4 o_color;\n"; 382 383 if (isVertexCase) 384 { 385 vtx << "out mediump vec4 v_color;\n"; 386 frag << "in mediump vec4 v_color;\n"; 387 } 388 else 389 { 390 vtx << "out mediump vec4 v_coords;\n"; 391 frag << "in mediump vec4 v_coords;\n"; 392 } 393 394 if (readAccess == INDEXACCESS_DYNAMIC) 395 op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n"; 396 else if (readAccess == INDEXACCESS_DYNAMIC_LOOP) 397 op << "uniform mediump int ui_four;\n"; 398 399 op << "uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n"; 400 401 vtx << "\n"; 402 vtx << "void main()\n"; 403 vtx << "{\n"; 404 vtx << " gl_Position = a_position;\n"; 405 406 frag << "\n"; 407 frag << "void main()\n"; 408 frag << "{\n"; 409 410 // Read array. 411 op << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n"; 412 if (readAccess == INDEXACCESS_STATIC) 413 { 414 op << " res += u_arr[0];\n"; 415 op << " res += u_arr[1];\n"; 416 op << " res += u_arr[2];\n"; 417 op << " res += u_arr[3];\n"; 418 } 419 else if (readAccess == INDEXACCESS_DYNAMIC) 420 { 421 op << " res += u_arr[ui_zero];\n"; 422 op << " res += u_arr[ui_one];\n"; 423 op << " res += u_arr[ui_two];\n"; 424 op << " res += u_arr[ui_three];\n"; 425 } 426 else if (readAccess == INDEXACCESS_STATIC_LOOP) 427 { 428 op << " for (int i = 0; i < 4; i++)\n"; 429 op << " res += u_arr[i];\n"; 430 } 431 else 432 { 433 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP); 434 op << " for (int i = 0; i < ui_four; i++)\n"; 435 op << " res += u_arr[i];\n"; 436 } 437 438 if (isVertexCase) 439 { 440 vtx << " v_color = vec4(res${PADDING});\n"; 441 frag << " o_color = v_color;\n"; 442 } 443 else 444 { 445 vtx << " v_coords = a_coords;\n"; 446 frag << " o_color = vec4(res${PADDING});\n"; 447 } 448 449 vtx << "}\n"; 450 frag << "}\n"; 451 452 // Fill in shader templates. 453 map<string, string> params; 454 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType))); 455 params.insert(pair<string, string>("ARRAY_LEN", "4")); 456 params.insert(pair<string, string>("PRECISION", "mediump")); 457 458 if (varType == TYPE_FLOAT) 459 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0")); 460 else if (varType == TYPE_FLOAT_VEC2) 461 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0")); 462 else if (varType == TYPE_FLOAT_VEC3) 463 params.insert(pair<string, string>("PADDING", ", 1.0")); 464 else 465 params.insert(pair<string, string>("PADDING", "")); 466 467 StringTemplate vertTemplate(vtx.str().c_str()); 468 StringTemplate fragTemplate(frag.str().c_str()); 469 string vertexShaderSource = vertTemplate.specialize(params); 470 string fragmentShaderSource = fragTemplate.specialize(params); 471 472 ShaderEvalFunc evalFunc = getArrayUniformEvalFunc(varType); 473 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, 474 vertexShaderSource.c_str(), fragmentShaderSource.c_str()); 475} 476 477static ShaderIndexingCase* createTmpArrayCase(Context& context, const char* caseName, const char* description, 478 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType, 479 IndexAccessType writeAccess, IndexAccessType readAccess) 480{ 481 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES || 482 glslVersion >= glu::GLSL_VERSION_330); 483 484 std::ostringstream vtx; 485 std::ostringstream frag; 486 std::ostringstream& op = isVertexCase ? vtx : frag; 487 488 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 489 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 490 491 vtx << "in highp vec4 a_position;\n"; 492 vtx << "in highp vec4 a_coords;\n"; 493 frag << "layout(location = 0) out mediump vec4 o_color;\n"; 494 495 if (isVertexCase) 496 { 497 vtx << "out mediump vec4 v_color;\n"; 498 frag << "in mediump vec4 v_color;\n"; 499 } 500 else 501 { 502 vtx << "out mediump vec4 v_coords;\n"; 503 frag << "in mediump vec4 v_coords;\n"; 504 } 505 506 if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC) 507 op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n"; 508 509 if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP) 510 op << "uniform mediump int ui_four;\n"; 511 512 vtx << "\n"; 513 vtx << "void main()\n"; 514 vtx << "{\n"; 515 vtx << " gl_Position = a_position;\n"; 516 517 frag << "\n"; 518 frag << "void main()\n"; 519 frag << "{\n"; 520 521 // Write array. 522 if (isVertexCase) 523 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n"; 524 else 525 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n"; 526 527 op << " ${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n"; 528 if (writeAccess == INDEXACCESS_STATIC) 529 { 530 op << " arr[0] = ${VAR_TYPE}(coords);\n"; 531 op << " arr[1] = ${VAR_TYPE}(coords) * 0.5;\n"; 532 op << " arr[2] = ${VAR_TYPE}(coords) * 0.25;\n"; 533 op << " arr[3] = ${VAR_TYPE}(coords) * 0.125;\n"; 534 } 535 else if (writeAccess == INDEXACCESS_DYNAMIC) 536 { 537 op << " arr[ui_zero] = ${VAR_TYPE}(coords);\n"; 538 op << " arr[ui_one] = ${VAR_TYPE}(coords) * 0.5;\n"; 539 op << " arr[ui_two] = ${VAR_TYPE}(coords) * 0.25;\n"; 540 op << " arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n"; 541 } 542 else if (writeAccess == INDEXACCESS_STATIC_LOOP) 543 { 544 op << " for (int i = 0; i < 4; i++)\n"; 545 op << " {\n"; 546 op << " arr[i] = ${VAR_TYPE}(coords);\n"; 547 op << " coords = coords * 0.5;\n"; 548 op << " }\n"; 549 } 550 else 551 { 552 DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP); 553 op << " for (int i = 0; i < ui_four; i++)\n"; 554 op << " {\n"; 555 op << " arr[i] = ${VAR_TYPE}(coords);\n"; 556 op << " coords = coords * 0.5;\n"; 557 op << " }\n"; 558 } 559 560 // Read array. 561 op << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n"; 562 if (readAccess == INDEXACCESS_STATIC) 563 { 564 op << " res += arr[0];\n"; 565 op << " res += arr[1];\n"; 566 op << " res += arr[2];\n"; 567 op << " res += arr[3];\n"; 568 } 569 else if (readAccess == INDEXACCESS_DYNAMIC) 570 { 571 op << " res += arr[ui_zero];\n"; 572 op << " res += arr[ui_one];\n"; 573 op << " res += arr[ui_two];\n"; 574 op << " res += arr[ui_three];\n"; 575 } 576 else if (readAccess == INDEXACCESS_STATIC_LOOP) 577 { 578 op << " for (int i = 0; i < 4; i++)\n"; 579 op << " res += arr[i];\n"; 580 } 581 else 582 { 583 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP); 584 op << " for (int i = 0; i < ui_four; i++)\n"; 585 op << " res += arr[i];\n"; 586 } 587 588 if (isVertexCase) 589 { 590 vtx << " v_color = vec4(res${PADDING});\n"; 591 frag << " o_color = v_color;\n"; 592 } 593 else 594 { 595 vtx << " v_coords = a_coords;\n"; 596 frag << " o_color = vec4(res${PADDING});\n"; 597 } 598 599 vtx << "}\n"; 600 frag << "}\n"; 601 602 // Fill in shader templates. 603 map<string, string> params; 604 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType))); 605 params.insert(pair<string, string>("ARRAY_LEN", "4")); 606 params.insert(pair<string, string>("PRECISION", "mediump")); 607 608 if (varType == TYPE_FLOAT) 609 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0")); 610 else if (varType == TYPE_FLOAT_VEC2) 611 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0")); 612 else if (varType == TYPE_FLOAT_VEC3) 613 params.insert(pair<string, string>("PADDING", ", 1.0")); 614 else 615 params.insert(pair<string, string>("PADDING", "")); 616 617 StringTemplate vertTemplate(vtx.str().c_str()); 618 StringTemplate fragTemplate(frag.str().c_str()); 619 string vertexShaderSource = vertTemplate.specialize(params); 620 string fragmentShaderSource = fragTemplate.specialize(params); 621 622 ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType); 623 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, 624 vertexShaderSource.c_str(), fragmentShaderSource.c_str()); 625} 626 627void evalGreenColor (ShaderEvalContext& c) 628{ 629 c.color = Vec4(0.0f, 1.0f, 0.0f, 1.0f); 630} 631 632static ShaderIndexingCase* createTmpArrayVertexIdCase (Context& context, const char* caseName, const char* description, 633 glu::GLSLVersion glslVersion) 634{ 635 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES || 636 glslVersion >= glu::GLSL_VERSION_330); 637 638 std::string vtx = glu::getGLSLVersionDeclaration(glslVersion) + std::string("\n" 639 "precision highp float;\n" 640 "in vec4 a_position;\n" 641 "out float color[4];\n" 642 "void main()\n" 643 "{\n" 644 " for(int i = 0; i < 4; i++)\n" 645 " {\n" 646 " int j = (gl_VertexID + i) % 4;\n" 647 " color[j] = (j % 2 == 0) ? 0.0 : 1.0;\n" 648 " }\n" 649 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n" 650 "}\n"); 651 652 std::string frag = glu::getGLSLVersionDeclaration(glslVersion) + std::string("\n" 653 "precision highp float;\n" 654 "in float color[4];\n" 655 "layout(location = 0) out vec4 o_color;\n" 656 "void main()\n" 657 "{\n" 658 " float temp[4];\n" 659 " for(int i = 0; i < 4; i++)\n" 660 " {\n" 661 " temp[i] = color[i];\n" 662 " o_color = vec4(temp[0], temp[1], temp[2], temp[3]);\n" 663 " }\n" 664 "}\n"); 665 666 return new ShaderIndexingCase(context, caseName, description, false, TYPE_FLOAT, evalGreenColor, 667 vtx.c_str(), frag.c_str()); 668} 669 670// VECTOR SUBSCRIPT. 671 672void evalSubscriptVec2(ShaderEvalContext& c) 673{ 674 c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y()); 675} 676void evalSubscriptVec3(ShaderEvalContext& c) 677{ 678 c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y() + 0.25f * c.coords.z()); 679} 680void evalSubscriptVec4(ShaderEvalContext& c) 681{ 682 c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y() + 0.25f * c.coords.z() + 0.125f * c.coords.w()); 683} 684 685static ShaderEvalFunc getVectorSubscriptEvalFunc(DataType dataType) 686{ 687 if (dataType == TYPE_FLOAT_VEC2) 688 return evalSubscriptVec2; 689 else if (dataType == TYPE_FLOAT_VEC3) 690 return evalSubscriptVec3; 691 else if (dataType == TYPE_FLOAT_VEC4) 692 return evalSubscriptVec4; 693 694 DE_ASSERT(DE_FALSE && "Invalid data type."); 695 return NULL; 696} 697 698static ShaderIndexingCase* createVectorSubscriptCase(Context& context, const char* caseName, const char* description, 699 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType, 700 VectorAccessType writeAccess, VectorAccessType readAccess) 701{ 702 std::ostringstream vtx; 703 std::ostringstream frag; 704 std::ostringstream& op = isVertexCase ? vtx : frag; 705 706 int vecLen = getDataTypeScalarSize(varType); 707 const char* vecLenName = getIntUniformName(vecLen); 708 709 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 710 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 711 712 vtx << "in highp vec4 a_position;\n"; 713 vtx << "in highp vec4 a_coords;\n"; 714 frag << "layout(location = 0) out mediump vec4 o_color;\n"; 715 716 if (isVertexCase) 717 { 718 vtx << "out mediump vec3 v_color;\n"; 719 frag << "in mediump vec3 v_color;\n"; 720 } 721 else 722 { 723 vtx << "out mediump vec4 v_coords;\n"; 724 frag << "in mediump vec4 v_coords;\n"; 725 } 726 727 if (writeAccess == SUBSCRIPT_DYNAMIC || readAccess == SUBSCRIPT_DYNAMIC) 728 { 729 op << "uniform mediump int ui_zero"; 730 if (vecLen >= 2) 731 op << ", ui_one"; 732 if (vecLen >= 3) 733 op << ", ui_two"; 734 if (vecLen >= 4) 735 op << ", ui_three"; 736 op << ";\n"; 737 } 738 739 if (writeAccess == SUBSCRIPT_DYNAMIC_LOOP || readAccess == SUBSCRIPT_DYNAMIC_LOOP) 740 op << "uniform mediump int " << vecLenName << ";\n"; 741 742 vtx << "\n"; 743 vtx << "void main()\n"; 744 vtx << "{\n"; 745 vtx << " gl_Position = a_position;\n"; 746 747 frag << "\n"; 748 frag << "void main()\n"; 749 frag << "{\n"; 750 751 // Write vector. 752 if (isVertexCase) 753 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n"; 754 else 755 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n"; 756 757 op << " ${PRECISION} ${VAR_TYPE} tmp;\n"; 758 if (writeAccess == DIRECT) 759 op << " tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n"; 760 else if (writeAccess == COMPONENT) 761 { 762 op << " tmp.x = coords.x;\n"; 763 if (vecLen >= 2) 764 op << " tmp.y = coords.y * 0.5;\n"; 765 if (vecLen >= 3) 766 op << " tmp.z = coords.z * 0.25;\n"; 767 if (vecLen >= 4) 768 op << " tmp.w = coords.w * 0.125;\n"; 769 } 770 else if (writeAccess == SUBSCRIPT_STATIC) 771 { 772 op << " tmp[0] = coords.x;\n"; 773 if (vecLen >= 2) 774 op << " tmp[1] = coords.y * 0.5;\n"; 775 if (vecLen >= 3) 776 op << " tmp[2] = coords.z * 0.25;\n"; 777 if (vecLen >= 4) 778 op << " tmp[3] = coords.w * 0.125;\n"; 779 } 780 else if (writeAccess == SUBSCRIPT_DYNAMIC) 781 { 782 op << " tmp[ui_zero] = coords.x;\n"; 783 if (vecLen >= 2) 784 op << " tmp[ui_one] = coords.y * 0.5;\n"; 785 if (vecLen >= 3) 786 op << " tmp[ui_two] = coords.z * 0.25;\n"; 787 if (vecLen >= 4) 788 op << " tmp[ui_three] = coords.w * 0.125;\n"; 789 } 790 else if (writeAccess == SUBSCRIPT_STATIC_LOOP) 791 { 792 op << " for (int i = 0; i < " << vecLen << "; i++)\n"; 793 op << " {\n"; 794 op << " tmp[i] = coords.x;\n"; 795 op << " coords = coords.${ROT_SWIZZLE} * 0.5;\n"; 796 op << " }\n"; 797 } 798 else 799 { 800 DE_ASSERT(writeAccess == SUBSCRIPT_DYNAMIC_LOOP); 801 op << " for (int i = 0; i < " << vecLenName << "; i++)\n"; 802 op << " {\n"; 803 op << " tmp[i] = coords.x;\n"; 804 op << " coords = coords.${ROT_SWIZZLE} * 0.5;\n"; 805 op << " }\n"; 806 } 807 808 // Read vector. 809 op << " ${PRECISION} float res = 0.0;\n"; 810 if (readAccess == DIRECT) 811 op << " res = dot(tmp, ${VAR_TYPE}(1.0));\n"; 812 else if (readAccess == COMPONENT) 813 { 814 op << " res += tmp.x;\n"; 815 if (vecLen >= 2) 816 op << " res += tmp.y;\n"; 817 if (vecLen >= 3) 818 op << " res += tmp.z;\n"; 819 if (vecLen >= 4) 820 op << " res += tmp.w;\n"; 821 } 822 else if (readAccess == SUBSCRIPT_STATIC) 823 { 824 op << " res += tmp[0];\n"; 825 if (vecLen >= 2) 826 op << " res += tmp[1];\n"; 827 if (vecLen >= 3) 828 op << " res += tmp[2];\n"; 829 if (vecLen >= 4) 830 op << " res += tmp[3];\n"; 831 } 832 else if (readAccess == SUBSCRIPT_DYNAMIC) 833 { 834 op << " res += tmp[ui_zero];\n"; 835 if (vecLen >= 2) 836 op << " res += tmp[ui_one];\n"; 837 if (vecLen >= 3) 838 op << " res += tmp[ui_two];\n"; 839 if (vecLen >= 4) 840 op << " res += tmp[ui_three];\n"; 841 } 842 else if (readAccess == SUBSCRIPT_STATIC_LOOP) 843 { 844 op << " for (int i = 0; i < " << vecLen << "; i++)\n"; 845 op << " res += tmp[i];\n"; 846 } 847 else 848 { 849 DE_ASSERT(readAccess == SUBSCRIPT_DYNAMIC_LOOP); 850 op << " for (int i = 0; i < " << vecLenName << "; i++)\n"; 851 op << " res += tmp[i];\n"; 852 } 853 854 if (isVertexCase) 855 { 856 vtx << " v_color = vec3(res);\n"; 857 frag << " o_color = vec4(v_color.rgb, 1.0);\n"; 858 } 859 else 860 { 861 vtx << " v_coords = a_coords;\n"; 862 frag << " o_color = vec4(vec3(res), 1.0);\n"; 863 } 864 865 vtx << "}\n"; 866 frag << "}\n"; 867 868 // Fill in shader templates. 869 static const char* s_swizzles[5] = { "", "x", "xy", "xyz", "xyzw" }; 870 static const char* s_rotSwizzles[5] = { "", "x", "yx", "yzx", "yzwx" }; 871 872 map<string, string> params; 873 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType))); 874 params.insert(pair<string, string>("PRECISION", "mediump")); 875 params.insert(pair<string, string>("SWIZZLE", s_swizzles[vecLen])); 876 params.insert(pair<string, string>("ROT_SWIZZLE", s_rotSwizzles[vecLen])); 877 878 StringTemplate vertTemplate(vtx.str().c_str()); 879 StringTemplate fragTemplate(frag.str().c_str()); 880 string vertexShaderSource = vertTemplate.specialize(params); 881 string fragmentShaderSource = fragTemplate.specialize(params); 882 883 ShaderEvalFunc evalFunc = getVectorSubscriptEvalFunc(varType); 884 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, 885 vertexShaderSource.c_str(), fragmentShaderSource.c_str()); 886} 887 888// MATRIX SUBSCRIPT. 889 890void evalSubscriptMat2(ShaderEvalContext& c) 891{ 892 c.color.xy() = c.coords.swizzle(0, 1) + 0.5f * c.coords.swizzle(1, 2); 893} 894void evalSubscriptMat2x3(ShaderEvalContext& c) 895{ 896 c.color.xyz() = c.coords.swizzle(0, 1, 2) + 0.5f * c.coords.swizzle(1, 2, 3); 897} 898void evalSubscriptMat2x4(ShaderEvalContext& c) 899{ 900 c.color = c.coords.swizzle(0, 1, 2, 3) + 0.5f * c.coords.swizzle(1, 2, 3, 0); 901} 902 903void evalSubscriptMat3x2(ShaderEvalContext& c) 904{ 905 c.color.xy() = c.coords.swizzle(0, 1) + 0.5f * c.coords.swizzle(1, 2) + 0.25f * c.coords.swizzle(2, 3); 906} 907void evalSubscriptMat3(ShaderEvalContext& c) 908{ 909 c.color.xyz() = c.coords.swizzle(0, 1, 2) + 0.5f * c.coords.swizzle(1, 2, 3) + 0.25f * c.coords.swizzle(2, 3, 0); 910} 911void evalSubscriptMat3x4(ShaderEvalContext& c) 912{ 913 c.color = c.coords.swizzle(0, 1, 2, 3) + 0.5f * c.coords.swizzle(1, 2, 3, 0) + 0.25f * c.coords.swizzle(2, 3, 0, 1); 914} 915 916void evalSubscriptMat4x2(ShaderEvalContext& c) 917{ 918 c.color.xy() = c.coords.swizzle(0, 1) + 0.5f * c.coords.swizzle(1, 2) + 0.25f * c.coords.swizzle(2, 3) + 919 0.125f * c.coords.swizzle(3, 0); 920} 921void evalSubscriptMat4x3(ShaderEvalContext& c) 922{ 923 c.color.xyz() = c.coords.swizzle(0, 1, 2) + 0.5f * c.coords.swizzle(1, 2, 3) + 0.25f * c.coords.swizzle(2, 3, 0) + 924 0.125f * c.coords.swizzle(3, 0, 1); 925} 926void evalSubscriptMat4(ShaderEvalContext& c) 927{ 928 c.color = c.coords + 0.5f * c.coords.swizzle(1, 2, 3, 0) + 0.25f * c.coords.swizzle(2, 3, 0, 1) + 929 0.125f * c.coords.swizzle(3, 0, 1, 2); 930} 931 932static ShaderEvalFunc getMatrixSubscriptEvalFunc(DataType dataType) 933{ 934 switch (dataType) 935 { 936 case TYPE_FLOAT_MAT2: 937 return evalSubscriptMat2; 938 case TYPE_FLOAT_MAT2X3: 939 return evalSubscriptMat2x3; 940 case TYPE_FLOAT_MAT2X4: 941 return evalSubscriptMat2x4; 942 case TYPE_FLOAT_MAT3X2: 943 return evalSubscriptMat3x2; 944 case TYPE_FLOAT_MAT3: 945 return evalSubscriptMat3; 946 case TYPE_FLOAT_MAT3X4: 947 return evalSubscriptMat3x4; 948 case TYPE_FLOAT_MAT4X2: 949 return evalSubscriptMat4x2; 950 case TYPE_FLOAT_MAT4X3: 951 return evalSubscriptMat4x3; 952 case TYPE_FLOAT_MAT4: 953 return evalSubscriptMat4; 954 955 default: 956 DE_ASSERT(DE_FALSE && "Invalid data type."); 957 return DE_NULL; 958 } 959} 960 961static ShaderIndexingCase* createMatrixSubscriptCase(Context& context, const char* caseName, const char* description, 962 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType, 963 IndexAccessType writeAccess, IndexAccessType readAccess) 964{ 965 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES || 966 glslVersion >= glu::GLSL_VERSION_330); 967 968 std::ostringstream vtx; 969 std::ostringstream frag; 970 std::ostringstream& op = isVertexCase ? vtx : frag; 971 972 int numCols = getDataTypeMatrixNumColumns(varType); 973 int numRows = getDataTypeMatrixNumRows(varType); 974 const char* matSizeName = getIntUniformName(numCols); 975 DataType vecType = getDataTypeFloatVec(numRows); 976 977 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 978 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 979 980 vtx << "in highp vec4 a_position;\n"; 981 vtx << "in highp vec4 a_coords;\n"; 982 frag << "layout(location = 0) out mediump vec4 o_color;\n"; 983 984 if (isVertexCase) 985 { 986 vtx << "out mediump vec4 v_color;\n"; 987 frag << "in mediump vec4 v_color;\n"; 988 } 989 else 990 { 991 vtx << "out mediump vec4 v_coords;\n"; 992 frag << "in mediump vec4 v_coords;\n"; 993 } 994 995 if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC) 996 { 997 op << "uniform mediump int ui_zero"; 998 if (numCols >= 2) 999 op << ", ui_one"; 1000 if (numCols >= 3) 1001 op << ", ui_two"; 1002 if (numCols >= 4) 1003 op << ", ui_three"; 1004 op << ";\n"; 1005 } 1006 1007 if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP) 1008 op << "uniform mediump int " << matSizeName << ";\n"; 1009 1010 vtx << "\n"; 1011 vtx << "void main()\n"; 1012 vtx << "{\n"; 1013 vtx << " gl_Position = a_position;\n"; 1014 1015 frag << "\n"; 1016 frag << "void main()\n"; 1017 frag << "{\n"; 1018 1019 // Write matrix. 1020 if (isVertexCase) 1021 op << " ${PRECISION} vec4 coords = a_coords;\n"; 1022 else 1023 op << " ${PRECISION} vec4 coords = v_coords;\n"; 1024 1025 op << " ${PRECISION} ${MAT_TYPE} tmp;\n"; 1026 if (writeAccess == INDEXACCESS_STATIC) 1027 { 1028 op << " tmp[0] = ${VEC_TYPE}(coords);\n"; 1029 if (numCols >= 2) 1030 op << " tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n"; 1031 if (numCols >= 3) 1032 op << " tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n"; 1033 if (numCols >= 4) 1034 op << " tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n"; 1035 } 1036 else if (writeAccess == INDEXACCESS_DYNAMIC) 1037 { 1038 op << " tmp[ui_zero] = ${VEC_TYPE}(coords);\n"; 1039 if (numCols >= 2) 1040 op << " tmp[ui_one] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n"; 1041 if (numCols >= 3) 1042 op << " tmp[ui_two] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n"; 1043 if (numCols >= 4) 1044 op << " tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n"; 1045 } 1046 else if (writeAccess == INDEXACCESS_STATIC_LOOP) 1047 { 1048 op << " for (int i = 0; i < " << numCols << "; i++)\n"; 1049 op << " {\n"; 1050 op << " tmp[i] = ${VEC_TYPE}(coords);\n"; 1051 op << " coords = coords.yzwx * 0.5;\n"; 1052 op << " }\n"; 1053 } 1054 else 1055 { 1056 DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP); 1057 op << " for (int i = 0; i < " << matSizeName << "; i++)\n"; 1058 op << " {\n"; 1059 op << " tmp[i] = ${VEC_TYPE}(coords);\n"; 1060 op << " coords = coords.yzwx * 0.5;\n"; 1061 op << " }\n"; 1062 } 1063 1064 // Read matrix. 1065 op << " ${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n"; 1066 if (readAccess == INDEXACCESS_STATIC) 1067 { 1068 op << " res += tmp[0];\n"; 1069 if (numCols >= 2) 1070 op << " res += tmp[1];\n"; 1071 if (numCols >= 3) 1072 op << " res += tmp[2];\n"; 1073 if (numCols >= 4) 1074 op << " res += tmp[3];\n"; 1075 } 1076 else if (readAccess == INDEXACCESS_DYNAMIC) 1077 { 1078 op << " res += tmp[ui_zero];\n"; 1079 if (numCols >= 2) 1080 op << " res += tmp[ui_one];\n"; 1081 if (numCols >= 3) 1082 op << " res += tmp[ui_two];\n"; 1083 if (numCols >= 4) 1084 op << " res += tmp[ui_three];\n"; 1085 } 1086 else if (readAccess == INDEXACCESS_STATIC_LOOP) 1087 { 1088 op << " for (int i = 0; i < " << numCols << "; i++)\n"; 1089 op << " res += tmp[i];\n"; 1090 } 1091 else 1092 { 1093 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP); 1094 op << " for (int i = 0; i < " << matSizeName << "; i++)\n"; 1095 op << " res += tmp[i];\n"; 1096 } 1097 1098 if (isVertexCase) 1099 { 1100 vtx << " v_color = vec4(res${PADDING});\n"; 1101 frag << " o_color = v_color;\n"; 1102 } 1103 else 1104 { 1105 vtx << " v_coords = a_coords;\n"; 1106 frag << " o_color = vec4(res${PADDING});\n"; 1107 } 1108 1109 vtx << "}\n"; 1110 frag << "}\n"; 1111 1112 // Fill in shader templates. 1113 map<string, string> params; 1114 params.insert(pair<string, string>("MAT_TYPE", getDataTypeName(varType))); 1115 params.insert(pair<string, string>("VEC_TYPE", getDataTypeName(vecType))); 1116 params.insert(pair<string, string>("PRECISION", "mediump")); 1117 1118 if (numRows == 2) 1119 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0")); 1120 else if (numRows == 3) 1121 params.insert(pair<string, string>("PADDING", ", 1.0")); 1122 else 1123 params.insert(pair<string, string>("PADDING", "")); 1124 1125 StringTemplate vertTemplate(vtx.str().c_str()); 1126 StringTemplate fragTemplate(frag.str().c_str()); 1127 string vertexShaderSource = vertTemplate.specialize(params); 1128 string fragmentShaderSource = fragTemplate.specialize(params); 1129 1130 ShaderEvalFunc evalFunc = getMatrixSubscriptEvalFunc(varType); 1131 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, 1132 vertexShaderSource.c_str(), fragmentShaderSource.c_str()); 1133} 1134 1135// ShaderIndexingTests. 1136 1137ShaderIndexingTests::ShaderIndexingTests(Context& context, glu::GLSLVersion glslVersion) 1138 : TestCaseGroup(context, "indexing", "Indexing Tests"), m_glslVersion(glslVersion) 1139{ 1140} 1141 1142ShaderIndexingTests::~ShaderIndexingTests(void) 1143{ 1144} 1145 1146void ShaderIndexingTests::init(void) 1147{ 1148 static const DataType s_floatAndVecTypes[] = { TYPE_FLOAT, TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4 }; 1149 1150 static const ShaderType s_shaderTypes[] = { SHADERTYPE_VERTEX, SHADERTYPE_FRAGMENT }; 1151 1152 // Varying array access cases. 1153 { 1154 TestCaseGroup* varyingGroup = new TestCaseGroup(m_context, "varying_array", "Varying array access tests."); 1155 addChild(varyingGroup); 1156 1157 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++) 1158 { 1159 DataType varType = s_floatAndVecTypes[typeNdx]; 1160 for (int vertAccess = 0; vertAccess < INDEXACCESS_LAST; vertAccess++) 1161 { 1162 for (int fragAccess = 0; fragAccess < INDEXACCESS_LAST; fragAccess++) 1163 { 1164 if (vertAccess == INDEXACCESS_STATIC && fragAccess == INDEXACCESS_STATIC) 1165 continue; 1166 1167 const char* vertAccessName = getIndexAccessTypeName((IndexAccessType)vertAccess); 1168 const char* fragAccessName = getIndexAccessTypeName((IndexAccessType)fragAccess); 1169 string name = 1170 string(getDataTypeName(varType)) + "_" + vertAccessName + "_write_" + fragAccessName + "_read"; 1171 string desc = string("Varying array with ") + vertAccessName + " write in vertex shader and " + 1172 fragAccessName + " read in fragment shader."; 1173 varyingGroup->addChild(createVaryingArrayCase(m_context, name.c_str(), desc.c_str(), m_glslVersion, 1174 varType, (IndexAccessType)vertAccess, 1175 (IndexAccessType)fragAccess)); 1176 } 1177 } 1178 } 1179 } 1180 1181 // Uniform array access cases. 1182 { 1183 TestCaseGroup* uniformGroup = new TestCaseGroup(m_context, "uniform_array", "Uniform array access tests."); 1184 addChild(uniformGroup); 1185 1186 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++) 1187 { 1188 DataType varType = s_floatAndVecTypes[typeNdx]; 1189 for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++) 1190 { 1191 const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess); 1192 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++) 1193 { 1194 ShaderType shaderType = s_shaderTypes[shaderTypeNdx]; 1195 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType); 1196 string name = string(getDataTypeName(varType)) + "_" + readAccessName + "_read_" + shaderTypeName; 1197 string desc = 1198 string("Uniform array with ") + readAccessName + " read in " + shaderTypeName + " shader."; 1199 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX); 1200 uniformGroup->addChild(createUniformArrayCase(m_context, name.c_str(), desc.c_str(), m_glslVersion, 1201 isVertexCase, varType, (IndexAccessType)readAccess)); 1202 } 1203 } 1204 } 1205 } 1206 1207 // Temporary array access cases. 1208 { 1209 TestCaseGroup* tmpGroup = new TestCaseGroup(m_context, "tmp_array", "Temporary array access tests."); 1210 addChild(tmpGroup); 1211 1212 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++) 1213 { 1214 DataType varType = s_floatAndVecTypes[typeNdx]; 1215 for (int isReadStatic = 0; isReadStatic < 2; isReadStatic++) 1216 { 1217 for (int access = INDEXACCESS_STATIC + 1; access < INDEXACCESS_LAST; access++) 1218 { 1219 IndexAccessType readAccess = isReadStatic ? INDEXACCESS_STATIC : (IndexAccessType)access; 1220 IndexAccessType writeAccess = isReadStatic ? (IndexAccessType)access : INDEXACCESS_STATIC; 1221 1222 const char* writeAccessName = getIndexAccessTypeName(writeAccess); 1223 const char* readAccessName = getIndexAccessTypeName(readAccess); 1224 1225 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++) 1226 { 1227 ShaderType shaderType = s_shaderTypes[shaderTypeNdx]; 1228 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType); 1229 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + 1230 readAccessName + "_read_" + shaderTypeName; 1231 string desc = string("Temporary array with ") + writeAccessName + " write and " + 1232 readAccessName + " read in " + shaderTypeName + " shader."; 1233 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX); 1234 tmpGroup->addChild(createTmpArrayCase(m_context, name.c_str(), desc.c_str(), m_glslVersion, 1235 isVertexCase, varType, (IndexAccessType)writeAccess, 1236 (IndexAccessType)readAccess)); 1237 } 1238 } 1239 } 1240 } 1241 1242 tmpGroup->addChild(createTmpArrayVertexIdCase(m_context, "vertexid", "", m_glslVersion)); 1243 } 1244 1245 // Vector indexing with subscripts. 1246 { 1247 TestCaseGroup* vecGroup = new TestCaseGroup(m_context, "vector_subscript", "Vector subscript indexing."); 1248 addChild(vecGroup); 1249 1250 static const DataType s_vectorTypes[] = { TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4 }; 1251 1252 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_vectorTypes); typeNdx++) 1253 { 1254 DataType varType = s_vectorTypes[typeNdx]; 1255 for (int isReadDirect = 0; isReadDirect < 2; isReadDirect++) 1256 { 1257 for (int access = SUBSCRIPT_STATIC; access < VECTORACCESS_LAST; access++) 1258 { 1259 VectorAccessType readAccess = isReadDirect ? DIRECT : (VectorAccessType)access; 1260 VectorAccessType writeAccess = isReadDirect ? (VectorAccessType)access : DIRECT; 1261 1262 const char* writeAccessName = getVectorAccessTypeName(writeAccess); 1263 const char* readAccessName = getVectorAccessTypeName(readAccess); 1264 1265 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++) 1266 { 1267 ShaderType shaderType = s_shaderTypes[shaderTypeNdx]; 1268 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType); 1269 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + 1270 readAccessName + "_read_" + shaderTypeName; 1271 string desc = string("Vector subscript access with ") + writeAccessName + " write and " + 1272 readAccessName + " read in " + shaderTypeName + " shader."; 1273 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX); 1274 vecGroup->addChild(createVectorSubscriptCase( 1275 m_context, name.c_str(), desc.c_str(), m_glslVersion, isVertexCase, varType, 1276 (VectorAccessType)writeAccess, (VectorAccessType)readAccess)); 1277 } 1278 } 1279 } 1280 } 1281 } 1282 1283 // Matrix indexing with subscripts. 1284 { 1285 TestCaseGroup* matGroup = new TestCaseGroup(m_context, "matrix_subscript", "Matrix subscript indexing."); 1286 addChild(matGroup); 1287 1288 static const DataType s_matrixTypes[] = { TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT2X4, 1289 TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT3X4, 1290 TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT4 }; 1291 1292 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_matrixTypes); typeNdx++) 1293 { 1294 DataType varType = s_matrixTypes[typeNdx]; 1295 for (int isReadStatic = 0; isReadStatic < 2; isReadStatic++) 1296 { 1297 for (int access = INDEXACCESS_STATIC + 1; access < INDEXACCESS_LAST; access++) 1298 { 1299 IndexAccessType readAccess = isReadStatic ? INDEXACCESS_STATIC : (IndexAccessType)access; 1300 IndexAccessType writeAccess = isReadStatic ? (IndexAccessType)access : INDEXACCESS_STATIC; 1301 1302 const char* writeAccessName = getIndexAccessTypeName(writeAccess); 1303 const char* readAccessName = getIndexAccessTypeName(readAccess); 1304 1305 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++) 1306 { 1307 ShaderType shaderType = s_shaderTypes[shaderTypeNdx]; 1308 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType); 1309 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + 1310 readAccessName + "_read_" + shaderTypeName; 1311 string desc = string("Vector subscript access with ") + writeAccessName + " write and " + 1312 readAccessName + " read in " + shaderTypeName + " shader."; 1313 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX); 1314 matGroup->addChild(createMatrixSubscriptCase( 1315 m_context, name.c_str(), desc.c_str(), m_glslVersion, isVertexCase, varType, 1316 (IndexAccessType)writeAccess, (IndexAccessType)readAccess)); 1317 } 1318 } 1319 } 1320 } 1321 } 1322} 1323 1324} // deqp 1325