1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL (ES) Module 3 * ----------------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Attribute location tests 22 *//*--------------------------------------------------------------------*/ 23 24#include "glsAttributeLocationTests.hpp" 25 26#include "tcuStringTemplate.hpp" 27#include "tcuTestLog.hpp" 28 29#include "gluDefs.hpp" 30#include "gluRenderContext.hpp" 31#include "gluShaderProgram.hpp" 32#include "gluShaderUtil.hpp" 33#include "gluStrUtil.hpp" 34 35#include "glwFunctions.hpp" 36 37#include "deStringUtil.hpp" 38 39#include <map> 40#include <set> 41#include <sstream> 42#include <string> 43#include <vector> 44 45#include <cstring> 46 47#include "glw.h" 48 49using tcu::TestLog; 50 51using std::string; 52using std::vector; 53using std::set; 54using std::map; 55using std::pair; 56 57using namespace deqp::gls::AttributeLocationTestUtil; 58 59namespace deqp 60{ 61namespace gls 62{ 63namespace 64{ 65 66deInt32 getBoundLocation (const map<string, deUint32>& bindings, const string& attrib) 67{ 68 std::map<string, deUint32>::const_iterator iter = bindings.find(attrib); 69 70 return (iter == bindings.end() ? (deInt32)Attribute::LOC_UNDEF : iter->second); 71} 72 73bool hasAttributeAliasing (const vector<Attribute>& attributes, const map<string, deUint32>& bindings) 74{ 75 vector<bool> reservedSpaces; 76 77 for (int attribNdx = 0; attribNdx < (int)attributes.size(); attribNdx++) 78 { 79 const deInt32 location = getBoundLocation(bindings, attributes[attribNdx].getName()); 80 const deUint32 size = attributes[attribNdx].getType().getLocationSize(); 81 82 if (location != Attribute::LOC_UNDEF) 83 { 84 if (reservedSpaces.size() < location + size) 85 reservedSpaces.resize(location + size, false); 86 87 for (int i = 0; i < (int)size; i++) 88 { 89 if (reservedSpaces[location + i]) 90 return true; 91 92 reservedSpaces[location + i] = true; 93 } 94 } 95 } 96 97 return false; 98} 99 100deInt32 getMaxAttributeLocations (glu::RenderContext& renderCtx) 101{ 102 const glw::Functions& gl = renderCtx.getFunctions(); 103 deInt32 maxAttribs; 104 105 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); 106 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()"); 107 108 return maxAttribs; 109} 110 111string generateAttributeDefinitions (const vector<Attribute>& attributes) 112{ 113 std::ostringstream src; 114 115 for (vector<Attribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) 116 { 117 if (iter->getLayoutLocation() != Attribute::LOC_UNDEF) 118 src << "layout(location = " << iter->getLayoutLocation() << ") "; 119 120 src << "${VTX_INPUT} mediump " 121 << iter->getType().getName() << " " 122 << iter->getName() 123 << (iter->getArraySize() != Attribute::NOT_ARRAY ? "[" + de::toString(iter->getArraySize()) + "]" : "") << ";\n"; 124 } 125 126 return src.str(); 127} 128 129string generateConditionUniformDefinitions (const vector<Attribute>& attributes) 130{ 131 std::ostringstream src; 132 set<string> conditions; 133 134 for (vector<Attribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) 135 { 136 if (iter->getCondition() != Cond::COND_NEVER && iter->getCondition() != Cond::COND_ALWAYS) 137 conditions.insert(iter->getCondition().getName()); 138 } 139 140 for (set<string>::const_iterator iter = conditions.begin(); iter != conditions.end(); ++iter) 141 src << "uniform mediump float u_" << (*iter) << ";\n"; 142 143 return src.str(); 144} 145 146string generateToVec4Expression (const Attribute& attrib, int id=-1) 147{ 148 const string variableName(attrib.getName() + (attrib.getArraySize() != Attribute::NOT_ARRAY ? "[" + de::toString(id) + "]" : "")); 149 std::ostringstream src; 150 151 switch (attrib.getType().getGLTypeEnum()) 152 { 153 case GL_INT_VEC2: 154 case GL_UNSIGNED_INT_VEC2: 155 case GL_FLOAT_VEC2: 156 src << "vec4(" << variableName << ".xy, " << variableName << ".yx)"; 157 break; 158 159 case GL_INT_VEC3: 160 case GL_UNSIGNED_INT_VEC3: 161 case GL_FLOAT_VEC3: 162 src << "vec4(" << variableName << ".xyz, " << variableName << ".x)"; 163 break; 164 165 default: 166 src << "vec4(" << variableName << ")"; 167 break; 168 } 169 170 return src.str(); 171} 172 173string generateOutputCode (const vector<Attribute>& attributes) 174{ 175 std::ostringstream src; 176 177 for (vector<Attribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) 178 { 179 if (iter->getCondition() == Cond::COND_NEVER) 180 { 181 src << 182 "\tif (0 != 0)\n" 183 "\t{\n"; 184 185 if (iter->getArraySize() == Attribute::NOT_ARRAY) 186 src << "\t\tcolor += " << generateToVec4Expression(*iter) << ";\n"; 187 else 188 { 189 for (int i = 0; i < iter->getArraySize(); i++) 190 src << "\t\tcolor += " << generateToVec4Expression(*iter, i) << ";\n"; 191 } 192 193 src << "\t}\n"; 194 } 195 else if (iter->getCondition() == Cond::COND_ALWAYS) 196 { 197 if (iter->getArraySize() == Attribute::NOT_ARRAY) 198 src << "\tcolor += " << generateToVec4Expression(*iter) << ";\n"; 199 else 200 { 201 for (int i = 0; i < iter->getArraySize(); i++) 202 src << "\tcolor += " << generateToVec4Expression(*iter, i) << ";\n"; 203 } 204 } 205 else 206 { 207 src << 208 "\tif (u_" << iter->getCondition().getName() << (iter->getCondition().getNegate() ? " != " : " == ") << "0.0)\n" 209 "\t{\n"; 210 211 if (iter->getArraySize() == Attribute::NOT_ARRAY) 212 src << "\t\tcolor += " << generateToVec4Expression(*iter) << ";\n"; 213 else 214 { 215 for (int i = 0; i < iter->getArraySize(); i++) 216 src << "\t\tcolor += " << generateToVec4Expression(*iter, i) << ";\n"; 217 } 218 219 src << 220 "\t}\n"; 221 } 222 } 223 224 return src.str(); 225} 226 227string generateVertexShaderTemplate (const vector<Attribute>& attributes) 228{ 229 std::ostringstream src; 230 231 src << "${VERSION}\n" 232 "${VTX_OUTPUT} mediump vec4 v_color;\n"; 233 234 src << generateAttributeDefinitions(attributes) 235 << "\n" 236 << generateConditionUniformDefinitions(attributes) 237 << "\n"; 238 239 src << "void main (void)\n" 240 "{\n" 241 "\tmediump vec4 color = vec4(0.0);\n" 242 "\n"; 243 244 src << generateOutputCode(attributes); 245 246 src << "\n" 247 "\tv_color = color;\n" 248 "\tgl_Position = color;\n" 249 "}\n"; 250 251 return src.str(); 252} 253 254string createVertexShaderSource (glu::RenderContext& renderCtx, const vector<Attribute>& attributes, bool attributeAliasing) 255{ 256 // \note On GLES only GLSL #version 100 supports aliasing 257 const glu::GLSLVersion contextGLSLVersion = glu::getContextTypeGLSLVersion(renderCtx.getType()); 258 const glu::GLSLVersion glslVersion = (attributeAliasing && glu::glslVersionIsES(contextGLSLVersion) ? glu::GLSL_VERSION_100_ES : contextGLSLVersion); 259 const bool usesInOutQualifiers = glu::glslVersionUsesInOutQualifiers(glslVersion); 260 const tcu::StringTemplate vertexShaderTemplate(generateVertexShaderTemplate(attributes)); 261 262 map<string, string> parameters; 263 264 parameters["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion); 265 parameters["VTX_OUTPUT"] = (usesInOutQualifiers ? "out" : "varying"); 266 parameters["VTX_INPUT"] = (usesInOutQualifiers ? "in" : "attribute"); 267 parameters["FRAG_INPUT"] = (usesInOutQualifiers ? "in" : "varying"); 268 parameters["FRAG_OUTPUT_VAR"] = (usesInOutQualifiers ? "dEQP_FragColor" : "gl_FragColor"); 269 parameters["FRAG_OUTPUT_DECLARATION"] = (usesInOutQualifiers 270 ? "layout(location=0) out mediump vec4 dEQP_FragColor;" 271 : ""); 272 273 return vertexShaderTemplate.specialize(parameters); 274} 275 276string createFragmentShaderSource (glu::RenderContext& renderCtx, bool attributeAliasing) 277{ 278 const char* const fragmentShaderSource = 279 "${VERSION}\n" 280 "${FRAG_OUTPUT_DECLARATION}\n" 281 "${FRAG_INPUT} mediump vec4 v_color;\n" 282 "void main (void)\n" 283 "{\n" 284 "\t${FRAG_OUTPUT_VAR} = v_color;\n" 285 "}\n"; 286 287 // \note On GLES only GLSL #version 100 supports aliasing 288 const glu::GLSLVersion contextGLSLVersion = glu::getContextTypeGLSLVersion(renderCtx.getType()); 289 const glu::GLSLVersion glslVersion = (attributeAliasing && glu::glslVersionIsES(contextGLSLVersion) ? glu::GLSL_VERSION_100_ES : contextGLSLVersion); 290 const tcu::StringTemplate fragmentShaderTemplate(fragmentShaderSource); 291 const bool usesInOutQualifiers = glu::glslVersionUsesInOutQualifiers(glslVersion); 292 293 map<string, string> parameters; 294 295 parameters["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion); 296 parameters["VTX_OUTPUT"] = (usesInOutQualifiers ? "out" : "varying"); 297 parameters["VTX_INPUT"] = (usesInOutQualifiers ? "in" : "attribute"); 298 parameters["FRAG_INPUT"] = (usesInOutQualifiers ? "in" : "varying"); 299 parameters["FRAG_OUTPUT_VAR"] = (usesInOutQualifiers ? "dEQP_FragColor" : "gl_FragColor"); 300 parameters["FRAG_OUTPUT_DECLARATION"] = (usesInOutQualifiers 301 ? "layout(location=0) out mediump vec4 dEQP_FragColor;" 302 : ""); 303 304 return fragmentShaderTemplate.specialize(parameters); 305} 306 307string getShaderInfoLog (const glw::Functions& gl, deUint32 shader) 308{ 309 deInt32 length = 0; 310 string infoLog; 311 312 gl.getShaderiv(shader, GL_INFO_LOG_LENGTH, &length); 313 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()"); 314 315 infoLog.resize(length, '\0'); 316 317 gl.getShaderInfoLog(shader, (glw::GLsizei)infoLog.length(), DE_NULL, &(infoLog[0])); 318 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog()"); 319 320 return infoLog; 321} 322 323bool getShaderCompileStatus (const glw::Functions& gl, deUint32 shader) 324{ 325 deInt32 status; 326 327 gl.getShaderiv(shader, GL_COMPILE_STATUS, &status); 328 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()"); 329 330 return status == GL_TRUE; 331} 332 333string getProgramInfoLog (const glw::Functions& gl, deUint32 program) 334{ 335 deInt32 length = 0; 336 string infoLog; 337 338 gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &length); 339 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()"); 340 341 infoLog.resize(length, '\0'); 342 343 gl.getProgramInfoLog(program, (glw::GLsizei)infoLog.length(), DE_NULL, &(infoLog[0])); 344 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog()"); 345 346 return infoLog; 347} 348 349bool getProgramLinkStatus (const glw::Functions& gl, deUint32 program) 350{ 351 deInt32 status; 352 353 gl.getProgramiv(program, GL_LINK_STATUS, &status); 354 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()"); 355 356 return status == GL_TRUE; 357} 358 359void logProgram (TestLog& log, const glw::Functions& gl, deUint32 program) 360{ 361 const bool programLinkOk = getProgramLinkStatus(gl, program); 362 const string programInfoLog = getProgramInfoLog(gl, program); 363 tcu::ScopedLogSection linkInfo (log, "Program Link Info", "Program Link Info"); 364 365 { 366 tcu::ScopedLogSection infoLogSection(log, "Info Log", "Info Log"); 367 368 log << TestLog::Message << programInfoLog << TestLog::EndMessage; 369 } 370 371 log << TestLog::Message << "Link result: " << (programLinkOk ? "Ok" : "Fail") << TestLog::EndMessage; 372} 373 374void logShaders (TestLog& log, 375 const string& vertexShaderSource, 376 const string& vertexShaderInfoLog, 377 bool vertexCompileOk, 378 const string& fragmentShaderSource, 379 const string& fragmentShaderInfoLog, 380 bool fragmentCompileOk) 381{ 382 // \todo [mika] Log as real shader elements. Currently not supported by TestLog. 383 { 384 tcu::ScopedLogSection shaderSection(log, "Vertex Shader Info", "Vertex Shader Info"); 385 386 log << TestLog::KernelSource(vertexShaderSource); 387 388 { 389 tcu::ScopedLogSection infoLogSection(log, "Info Log", "Info Log"); 390 391 log << TestLog::Message << vertexShaderInfoLog << TestLog::EndMessage; 392 } 393 394 log << TestLog::Message << "Compilation result: " << (vertexCompileOk ? "Ok" : "Failed") << TestLog::EndMessage; 395 } 396 397 { 398 tcu::ScopedLogSection shaderSection(log, "Fragment Shader Info", "Fragment Shader Info"); 399 400 log << TestLog::KernelSource(fragmentShaderSource); 401 402 { 403 tcu::ScopedLogSection infoLogSection(log, "Info Log", "Info Log"); 404 405 log << TestLog::Message << fragmentShaderInfoLog << TestLog::EndMessage; 406 } 407 408 log << TestLog::Message << "Compilation result: " << (fragmentCompileOk ? "Ok" : "Failed") << TestLog::EndMessage; 409 } 410} 411 412pair<deUint32, deUint32> createAndAttachShaders (TestLog& log, glu::RenderContext& renderCtx, deUint32 program, const vector<Attribute>& attributes, bool attributeAliasing) 413{ 414 const glw::Functions& gl = renderCtx.getFunctions(); 415 const string vertexShaderSource = createVertexShaderSource(renderCtx, attributes, attributeAliasing); 416 const string fragmentShaderSource = createFragmentShaderSource(renderCtx, attributeAliasing); 417 418 const deUint32 vertexShader = gl.createShader(GL_VERTEX_SHADER); 419 const deUint32 fragmentShader = gl.createShader(GL_FRAGMENT_SHADER); 420 421 try 422 { 423 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader()"); 424 425 { 426 const char* const vertexShaderString = vertexShaderSource.c_str(); 427 const char* const fragmentShaderString = fragmentShaderSource.c_str(); 428 429 gl.shaderSource(vertexShader, 1, &vertexShaderString, DE_NULL); 430 gl.shaderSource(fragmentShader, 1, &fragmentShaderString, DE_NULL); 431 432 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()"); 433 } 434 435 gl.compileShader(vertexShader); 436 gl.compileShader(fragmentShader); 437 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader()"); 438 439 gl.attachShader(program, vertexShader); 440 gl.attachShader(program, fragmentShader); 441 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader()"); 442 443 { 444 const bool vertexCompileOk = getShaderCompileStatus(gl, vertexShader); 445 const bool fragmentCompileOk = getShaderCompileStatus(gl, fragmentShader); 446 447 const string vertexShaderInfoLog = getShaderInfoLog(gl, vertexShader); 448 const string fragmentShaderInfoLog = getShaderInfoLog(gl, fragmentShader); 449 450 logShaders(log, vertexShaderSource, vertexShaderInfoLog, vertexCompileOk, fragmentShaderSource, fragmentShaderInfoLog, fragmentCompileOk); 451 452 TCU_CHECK_MSG(vertexCompileOk, "Vertex shader compilation failed"); 453 TCU_CHECK_MSG(fragmentCompileOk, "Fragment shader compilation failed"); 454 } 455 456 gl.deleteShader(vertexShader); 457 gl.deleteShader(fragmentShader); 458 459 return pair<deUint32, deUint32>(vertexShader, fragmentShader); 460 } 461 catch (...) 462 { 463 if (vertexShader != 0) 464 gl.deleteShader(vertexShader); 465 466 if (fragmentShader != 0) 467 gl.deleteShader(fragmentShader); 468 469 throw; 470 } 471} 472 473void bindAttributes (TestLog& log, const glw::Functions& gl, deUint32 program, const vector<Bind>& binds) 474{ 475 for (vector<Bind>::const_iterator iter = binds.begin(); iter != binds.end(); ++iter) 476 { 477 log << TestLog::Message << "Bind attribute: '" << iter->getAttributeName() << "' to " << iter->getLocation() << TestLog::EndMessage; 478 gl.bindAttribLocation(program, iter->getLocation(), iter->getAttributeName().c_str()); 479 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation()"); 480 } 481} 482 483void logAttributes (TestLog& log, const vector<Attribute>& attributes) 484{ 485 for (int attribNdx = 0; attribNdx < (int)attributes.size(); attribNdx++) 486 { 487 const Attribute& attrib = attributes[attribNdx]; 488 489 log << TestLog::Message 490 << "Type: " << attrib.getType().getName() 491 << ", Name: " << attrib.getName() 492 << (attrib.getLayoutLocation() != Attribute::LOC_UNDEF ? ", Layout location " + de::toString(attrib.getLayoutLocation()) : "") 493 << TestLog::EndMessage; 494 } 495} 496 497bool checkActiveAttribQuery (TestLog& log, const glw::Functions& gl, deUint32 program, const vector<Attribute>& attributes) 498{ 499 deInt32 activeAttribCount = 0; 500 set<string> activeAttributes; 501 bool isOk = true; 502 503 gl.getProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttribCount); 504 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttribCount)"); 505 506 for (int activeAttribNdx = 0; activeAttribNdx < activeAttribCount; activeAttribNdx++) 507 { 508 char name[128]; 509 const size_t maxNameSize = DE_LENGTH_OF_ARRAY(name) - 1; 510 deInt32 length = 0; 511 deInt32 size = 0; 512 deUint32 type = 0; 513 514 std::memset(name, 0, sizeof(name)); 515 516 gl.getActiveAttrib(program, activeAttribNdx, maxNameSize, &length, &size, &type, name); 517 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveAttrib()"); 518 519 log << TestLog::Message 520 << "glGetActiveAttrib(program" 521 << ", index=" << activeAttribNdx 522 << ", bufSize=" << maxNameSize 523 << ", length=" << length 524 << ", size=" << size 525 << ", type=" << glu::getShaderVarTypeStr(type) 526 << ", name='" << name << "')" << TestLog::EndMessage; 527 528 { 529 bool found = false; 530 531 for (int attribNdx = 0; attribNdx < (int)attributes.size(); attribNdx++) 532 { 533 const Attribute& attrib = attributes[attribNdx]; 534 535 if (attrib.getName() == name) 536 { 537 if (type != attrib.getType().getGLTypeEnum()) 538 { 539 log << TestLog::Message 540 << "Error: Wrong type " << glu::getShaderVarTypeStr(type) 541 << " expected " << glu::getShaderVarTypeStr(attrib.getType().getGLTypeEnum()) 542 << TestLog::EndMessage; 543 544 isOk = false; 545 } 546 547 if (attrib.getArraySize() == Attribute::NOT_ARRAY) 548 { 549 if (size != 1) 550 { 551 log << TestLog::Message << "Error: Wrong size " << size << " expected " << 1 << TestLog::EndMessage; 552 isOk = false; 553 } 554 } 555 else 556 { 557 if (size != attrib.getArraySize()) 558 { 559 log << TestLog::Message << "Error: Wrong size " << size << " expected " << attrib.getArraySize() << TestLog::EndMessage; 560 isOk = false; 561 } 562 } 563 564 found = true; 565 break; 566 } 567 } 568 569 if (!found) 570 { 571 log << TestLog::Message << "Error: Unknown attribute '" << name << "' returned by glGetActiveAttrib()." << TestLog::EndMessage; 572 isOk = false; 573 } 574 } 575 576 activeAttributes.insert(name); 577 } 578 579 for (int attribNdx = 0; attribNdx < (int)attributes.size(); attribNdx++) 580 { 581 const Attribute& attrib = attributes[attribNdx]; 582 const bool isActive = attrib.getCondition() != Cond::COND_NEVER; 583 584 if (isActive) 585 { 586 if (activeAttributes.find(attrib.getName()) == activeAttributes.end()) 587 { 588 log << TestLog::Message << "Error: Active attribute " << attrib.getName() << " wasn't returned by glGetActiveAttrib()." << TestLog::EndMessage; 589 isOk = false; 590 } 591 } 592 else 593 { 594 if (activeAttributes.find(attrib.getName()) != activeAttributes.end()) 595 log << TestLog::Message << "Note: Inactive attribute " << attrib.getName() << " was returned by glGetActiveAttrib()." << TestLog::EndMessage; 596 } 597 } 598 599 return isOk; 600} 601 602bool checkAttribLocationQuery (TestLog& log, const glw::Functions& gl, deUint32 program, const vector<Attribute>& attributes, const map<string, deUint32>& bindings) 603{ 604 bool isOk = true; 605 606 for (int attribNdx = 0; attribNdx < (int)attributes.size(); attribNdx++) 607 { 608 const Attribute& attrib = attributes[attribNdx]; 609 const deInt32 expectedLocation = (attrib.getLayoutLocation() != Attribute::LOC_UNDEF ? attrib.getLayoutLocation() : getBoundLocation(bindings, attrib.getName())); 610 const deInt32 location = gl.getAttribLocation(program, attrib.getName().c_str()); 611 612 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()"); 613 614 log << TestLog::Message 615 << location << " = glGetAttribLocation(program, \"" << attrib.getName() << "\")" 616 << (attrib.getCondition() != Cond::COND_NEVER && expectedLocation != Attribute::LOC_UNDEF ? ", expected " + de::toString(expectedLocation) : "") 617 << "." << TestLog::EndMessage; 618 619 if (attrib.getCondition() == Cond::COND_NEVER && location != -1) 620 log << TestLog::Message << "\tNote: Inactive attribute with location." << TestLog::EndMessage; 621 622 if (attrib.getCondition() != Cond::COND_NEVER && expectedLocation != Attribute::LOC_UNDEF && expectedLocation != location) 623 log << TestLog::Message << "\tError: Invalid attribute location." << TestLog::EndMessage; 624 625 isOk &= (attrib.getCondition() == Cond::COND_NEVER || expectedLocation == Attribute::LOC_UNDEF || expectedLocation == location); 626 } 627 628 return isOk; 629} 630 631bool checkQuery (TestLog& log, const glw::Functions& gl, deUint32 program, const vector<Attribute>& attributes, const map<string, deUint32>& bindings) 632{ 633 bool isOk = checkActiveAttribQuery(log, gl, program, attributes); 634 635 if (!checkAttribLocationQuery(log, gl, program, attributes, bindings)) 636 isOk = false; 637 638 return isOk; 639} 640 641string generateTestName (const AttribType& type, int arraySize) 642{ 643 return type.getName() + (arraySize != Attribute::NOT_ARRAY ? "_array_" + de::toString(arraySize) : ""); 644} 645 646} // anonymous 647 648namespace AttributeLocationTestUtil 649{ 650 651AttribType::AttribType (const string& name, deUint32 localSize, deUint32 typeEnum) 652 : m_name (name) 653 , m_locationSize (localSize) 654 , m_glTypeEnum (typeEnum) 655{ 656} 657 658Cond::Cond (const string& name, bool negate) 659 : m_negate (negate) 660 , m_name (name) 661{ 662} 663 664Cond::Cond (ConstCond cond) 665 : m_negate (cond != COND_NEVER) 666 , m_name ("__always__") 667{ 668 DE_ASSERT(cond == COND_ALWAYS || cond == COND_NEVER); 669} 670 671Attribute::Attribute (const AttribType& type, const string& name, deInt32 layoutLocation, const Cond& cond, int arraySize) 672 : m_type (type) 673 , m_name (name) 674 , m_layoutLocation (layoutLocation) 675 , m_cond (cond) 676 , m_arraySize (arraySize) 677{ 678} 679 680Bind::Bind (const std::string& attribute, deUint32 location) 681 : m_attribute (attribute) 682 , m_location (location) 683{ 684} 685 686void runTest (tcu::TestContext& testCtx, 687 glu::RenderContext& renderCtx, 688 const vector<Attribute>& attributes, 689 const vector<Bind>& preAttachBind, 690 const vector<Bind>& preLinkBind, 691 const vector<Bind>& postLinkBind, 692 bool relink, 693 bool reattach = false, 694 const vector<Attribute>& reattachAttributes = vector<Attribute>()) 695{ 696 TestLog& log = testCtx.getLog(); 697 const glw::Functions& gl = renderCtx.getFunctions(); 698 deUint32 program = 0; 699 pair<deUint32, deUint32> shaders; 700 701 try 702 { 703 bool isOk = true; 704 map<string, deUint32> activeBindings; 705 706 for (int bindNdx = 0; bindNdx < (int)preAttachBind.size(); bindNdx++) 707 activeBindings[preAttachBind[bindNdx].getAttributeName()] = preAttachBind[bindNdx].getLocation(); 708 709 for (int bindNdx = 0; bindNdx < (int)preLinkBind.size(); bindNdx++) 710 activeBindings[preLinkBind[bindNdx].getAttributeName()] = preLinkBind[bindNdx].getLocation(); 711 712 { 713 tcu::ScopedLogSection section(log, "Attributes", "Attribute information"); 714 logAttributes(testCtx.getLog(), attributes); 715 } 716 717 log << TestLog::Message << "Create program." << TestLog::EndMessage; 718 program = gl.createProgram(); 719 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram()"); 720 721 if (!preAttachBind.empty()) 722 bindAttributes(log, gl, program, preAttachBind); 723 724 log << TestLog::Message << "Create and attach shaders to program." << TestLog::EndMessage; 725 shaders = createAndAttachShaders(log, renderCtx, program, attributes, hasAttributeAliasing(attributes, activeBindings)); 726 727 if (!preLinkBind.empty()) 728 bindAttributes(log, gl, program, preLinkBind); 729 730 log << TestLog::Message << "Link program." << TestLog::EndMessage; 731 732 gl.linkProgram(program); 733 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram()"); 734 735 logProgram(log, gl, program); 736 TCU_CHECK_MSG(getProgramLinkStatus(gl, program), "Program link failed"); 737 738 if (!checkQuery(log, gl, program, attributes, activeBindings)) 739 isOk = false; 740 741 if (!postLinkBind.empty()) 742 { 743 bindAttributes(log, gl, program, postLinkBind); 744 745 if (!checkQuery(log, gl, program, attributes, activeBindings)) 746 isOk = false; 747 } 748 749 if (relink) 750 { 751 log << TestLog::Message << "Relink program." << TestLog::EndMessage; 752 gl.linkProgram(program); 753 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram()"); 754 755 logProgram(log, gl, program); 756 TCU_CHECK_MSG(getProgramLinkStatus(gl, program), "Program link failed"); 757 758 for (int bindNdx = 0; bindNdx < (int)postLinkBind.size(); bindNdx++) 759 activeBindings[postLinkBind[bindNdx].getAttributeName()] = postLinkBind[bindNdx].getLocation(); 760 761 if (!checkQuery(log, gl, program, attributes, activeBindings)) 762 isOk = false; 763 } 764 765 if (reattach) 766 { 767 gl.detachShader(program, shaders.first); 768 gl.detachShader(program, shaders.second); 769 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader()"); 770 771 log << TestLog::Message << "Create and attach shaders to program." << TestLog::EndMessage; 772 createAndAttachShaders(log, renderCtx, program, reattachAttributes, hasAttributeAliasing(reattachAttributes, activeBindings)); 773 774 log << TestLog::Message << "Relink program." << TestLog::EndMessage; 775 gl.linkProgram(program); 776 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram()"); 777 778 logProgram(log, gl, program); 779 TCU_CHECK_MSG(getProgramLinkStatus(gl, program), "Program link failed"); 780 781 if (!checkQuery(log, gl, program, reattachAttributes, activeBindings)) 782 isOk = false; 783 } 784 785 gl.deleteProgram(program); 786 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram()"); 787 788 if (isOk) 789 testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 790 else 791 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 792 } 793 catch (...) 794 { 795 if (program) 796 gl.deleteProgram(program); 797 798 throw; 799 } 800} 801 802} // AttributeLocationTestUtil 803 804BindAttributeTest::BindAttributeTest (tcu::TestContext& testCtx, 805 glu::RenderContext& renderCtx, 806 const AttribType& type, 807 int arraySize) 808 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 809 , m_renderCtx (renderCtx) 810 , m_type (type) 811 , m_arraySize (arraySize) 812{ 813} 814 815tcu::TestCase::IterateResult BindAttributeTest::iterate (void) 816{ 817 const vector<Bind> noBindings; 818 819 vector<Attribute> attributes; 820 vector<Bind> bindings; 821 822 attributes.push_back(Attribute(m_type, "a_0", Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 823 bindings.push_back(Bind("a_0", 3)); 824 825 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 826 return STOP; 827} 828 829BindMaxAttributesTest::BindMaxAttributesTest (tcu::TestContext& testCtx, 830 glu::RenderContext& renderCtx, 831 const AttribType& type, 832 int arraySize) 833 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 834 , m_renderCtx (renderCtx) 835 , m_type (type) 836 , m_arraySize (arraySize) 837{ 838} 839 840tcu::TestCase::IterateResult BindMaxAttributesTest::iterate (void) 841{ 842 const vector<Bind> noBindings; 843 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 844 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 845 846 vector<Attribute> attributes; 847 vector<Bind> bindings; 848 int ndx = 0; 849 850 m_testCtx.getLog() << TestLog::Message << "GL_MAX_VERTEX_ATTRIBS: " << maxAttributes << TestLog::EndMessage; 851 852 for (int loc = maxAttributes - (arrayElementCount * m_type.getLocationSize()); loc >= 0; loc -= (arrayElementCount * m_type.getLocationSize())) 853 { 854 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx), Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 855 bindings.push_back(Bind("a_" + de::toString(ndx), loc)); 856 ndx++; 857 } 858 859 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 860 return STOP; 861} 862 863BindAliasingAttributeTest::BindAliasingAttributeTest (tcu::TestContext& testCtx, 864 glu::RenderContext& renderCtx, 865 const AttribType& type, 866 int offset, 867 int arraySize) 868 : TestCase (testCtx, ("cond_" + generateTestName(type, arraySize) + (offset != 0 ? "_offset_" + de::toString(offset) : "")).c_str(), 869 ("cond_" + generateTestName(type, arraySize) + (offset != 0 ? "_offset_" + de::toString(offset) : "")).c_str()) 870 , m_renderCtx (renderCtx) 871 , m_type (type) 872 , m_offset (offset) 873 , m_arraySize (arraySize) 874{ 875} 876 877tcu::TestCase::IterateResult BindAliasingAttributeTest::iterate (void) 878{ 879 const vector<Bind> noBindings; 880 881 vector<Attribute> attributes; 882 vector<Bind> bindings; 883 884 attributes.push_back(Attribute(m_type, "a_0", Attribute::LOC_UNDEF, Cond("A", true), m_arraySize)); 885 attributes.push_back(Attribute(AttribType("vec4", 1, GL_FLOAT_VEC4), "a_1", Attribute::LOC_UNDEF, Cond("A", false))); 886 bindings.push_back(Bind("a_0", 1)); 887 bindings.push_back(Bind("a_1", 1 + m_offset)); 888 889 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 890 return STOP; 891} 892 893BindMaxAliasingAttributeTest::BindMaxAliasingAttributeTest (tcu::TestContext& testCtx, 894 glu::RenderContext& renderCtx, 895 const AttribType& type, 896 int arraySize) 897 : TestCase (testCtx, ("max_cond_" + generateTestName(type, arraySize)).c_str(), ("max_cond_" + generateTestName(type, arraySize)).c_str()) 898 , m_renderCtx (renderCtx) 899 , m_type (type) 900 , m_arraySize (arraySize) 901{ 902} 903 904tcu::TestCase::IterateResult BindMaxAliasingAttributeTest::iterate (void) 905{ 906 const vector<Bind> noBindings; 907 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 908 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 909 910 vector<Attribute> attributes; 911 vector<Bind> bindings; 912 int ndx = 0; 913 914 m_testCtx.getLog() << TestLog::Message << "GL_MAX_VERTEX_ATTRIBS: " << maxAttributes << TestLog::EndMessage; 915 916 for (int loc = maxAttributes - arrayElementCount * m_type.getLocationSize(); loc >= 0; loc -= m_type.getLocationSize() * arrayElementCount) 917 { 918 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx), Attribute::LOC_UNDEF, Cond("A", true))); 919 bindings.push_back(Bind("a_" + de::toString(ndx), loc)); 920 921 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx + maxAttributes), Attribute::LOC_UNDEF, Cond("A", false))); 922 bindings.push_back(Bind("a_" + de::toString(ndx + maxAttributes), loc)); 923 ndx++; 924 } 925 926 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 927 return STOP; 928} 929 930BindHoleAttributeTest::BindHoleAttributeTest (tcu::TestContext& testCtx, 931 glu::RenderContext& renderCtx, 932 const AttribType& type, 933 int arraySize) 934 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 935 , m_renderCtx (renderCtx) 936 , m_type (type) 937 , m_arraySize (arraySize) 938{ 939} 940 941tcu::TestCase::IterateResult BindHoleAttributeTest::iterate (void) 942{ 943 const vector<Bind> noBindings; 944 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 945 const AttribType vec4("vec4", 1, GL_FLOAT_VEC4); 946 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 947 948 vector<Attribute> attributes; 949 vector<Bind> bindings; 950 int ndx; 951 952 attributes.push_back(Attribute(vec4, "a_0")); 953 bindings.push_back(Bind("a_0", 0)); 954 955 attributes.push_back(Attribute(m_type, "a_1", Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 956 957 ndx = 2; 958 for (int loc = 1 + m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) 959 { 960 attributes.push_back(Attribute(vec4, "a_" + de::toString(ndx))); 961 bindings.push_back(Bind("a_" + de::toString(ndx), loc)); 962 963 ndx++; 964 } 965 966 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 967 return STOP; 968} 969 970BindInactiveAliasingAttributeTest::BindInactiveAliasingAttributeTest (tcu::TestContext& testCtx, 971 glu::RenderContext& renderCtx, 972 const AttribType& type, 973 int arraySize) 974 : TestCase (testCtx, ("max_inactive_" + generateTestName(type, arraySize)).c_str(), 975 ("max_inactive_" + generateTestName(type, arraySize)).c_str()) 976 , m_renderCtx (renderCtx) 977 , m_type (type) 978 , m_arraySize (arraySize) 979{ 980} 981 982tcu::TestCase::IterateResult BindInactiveAliasingAttributeTest::iterate (void) 983{ 984 const vector<Bind> noBindings; 985 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 986 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 987 988 vector<Attribute> attributes; 989 vector<Bind> bindings; 990 int ndx = 0; 991 992 m_testCtx.getLog() << TestLog::Message << "GL_MAX_VERTEX_ATTRIBS: " << maxAttributes << TestLog::EndMessage; 993 994 for (int loc = maxAttributes - arrayElementCount * m_type.getLocationSize(); loc >= 0; loc -= m_type.getLocationSize() * arrayElementCount) 995 { 996 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx), Attribute::LOC_UNDEF, Cond("A"))); 997 bindings.push_back(Bind("a_" + de::toString(ndx), loc)); 998 999 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx + maxAttributes), Attribute::LOC_UNDEF, Cond::COND_NEVER)); 1000 bindings.push_back(Bind("a_" + de::toString(ndx + maxAttributes), loc)); 1001 ndx++; 1002 } 1003 1004 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 1005 return STOP; 1006} 1007 1008PreAttachBindAttributeTest::PreAttachBindAttributeTest (tcu::TestContext& testCtx, 1009 glu::RenderContext& renderCtx) 1010 : TestCase (testCtx, "pre_attach", "pre_attach") 1011 , m_renderCtx (renderCtx) 1012{ 1013} 1014 1015tcu::TestCase::IterateResult PreAttachBindAttributeTest::iterate (void) 1016{ 1017 const vector<Bind> noBindings; 1018 1019 vector<Attribute> attributes; 1020 vector<Bind> bindings; 1021 1022 attributes.push_back(Attribute(AttribType("vec4", 1, GL_FLOAT_VEC4), "a_0")); 1023 bindings.push_back(Bind("a_0", 3)); 1024 1025 runTest(m_testCtx, m_renderCtx, attributes, bindings, noBindings, noBindings, false); 1026 return STOP; 1027} 1028 1029PreLinkBindAttributeTest::PreLinkBindAttributeTest (tcu::TestContext& testCtx, 1030 glu::RenderContext& renderCtx) 1031 : TestCase (testCtx, "pre_link", "pre_link") 1032 , m_renderCtx (renderCtx) 1033{ 1034} 1035 1036tcu::TestCase::IterateResult PreLinkBindAttributeTest::iterate (void) 1037{ 1038 const vector<Bind> noBindings; 1039 1040 vector<Attribute> attributes; 1041 vector<Bind> bindings; 1042 1043 attributes.push_back(Attribute(AttribType("vec4", 1, GL_FLOAT_VEC4), "a_0")); 1044 bindings.push_back(Bind("a_0", 3)); 1045 1046 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 1047 return STOP; 1048} 1049 1050PostLinkBindAttributeTest::PostLinkBindAttributeTest (tcu::TestContext& testCtx, 1051 glu::RenderContext& renderCtx) 1052 : TestCase (testCtx, "post_link", "post_link") 1053 , m_renderCtx (renderCtx) 1054{ 1055} 1056 1057tcu::TestCase::IterateResult PostLinkBindAttributeTest::iterate (void) 1058{ 1059 const vector<Bind> noBindings; 1060 1061 vector<Attribute> attributes; 1062 vector<Bind> bindings; 1063 1064 attributes.push_back(Attribute(AttribType("vec4", 1, GL_FLOAT_VEC4), "a_0")); 1065 bindings.push_back(Bind("a_0", 3)); 1066 1067 runTest(m_testCtx, m_renderCtx, attributes, noBindings, noBindings, bindings, false); 1068 return STOP; 1069} 1070 1071LocationAttributeTest::LocationAttributeTest (tcu::TestContext& testCtx, 1072 glu::RenderContext& renderCtx, 1073 const AttribType& type, 1074 int arraySize) 1075 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1076 , m_renderCtx (renderCtx) 1077 , m_type (type) 1078 , m_arraySize (arraySize) 1079{ 1080} 1081 1082tcu::TestCase::IterateResult LocationAttributeTest::iterate (void) 1083{ 1084 const vector<Bind> noBindings; 1085 1086 vector<Attribute> attributes; 1087 1088 attributes.push_back(Attribute(m_type, "a_0", 3, Cond::COND_ALWAYS, m_arraySize)); 1089 1090 runTest(m_testCtx, m_renderCtx, attributes, noBindings, noBindings, noBindings, false); 1091 return STOP; 1092} 1093 1094LocationMaxAttributesTest::LocationMaxAttributesTest (tcu::TestContext& testCtx, 1095 glu::RenderContext& renderCtx, 1096 const AttribType& type, 1097 int arraySize) 1098 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1099 , m_renderCtx (renderCtx) 1100 , m_type (type) 1101 , m_arraySize (arraySize) 1102{ 1103} 1104 1105tcu::TestCase::IterateResult LocationMaxAttributesTest::iterate (void) 1106{ 1107 const vector<Bind> noBindings; 1108 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 1109 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 1110 1111 vector<Attribute> attributes; 1112 int ndx = 0; 1113 1114 m_testCtx.getLog() << TestLog::Message << "GL_MAX_VERTEX_ATTRIBS: " << maxAttributes << TestLog::EndMessage; 1115 1116 for (int loc = maxAttributes - (arrayElementCount * m_type.getLocationSize()); loc >= 0; loc -= (arrayElementCount * m_type.getLocationSize())) 1117 { 1118 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx), loc, Cond::COND_ALWAYS, m_arraySize)); 1119 ndx++; 1120 } 1121 1122 runTest(m_testCtx, m_renderCtx, attributes, noBindings, noBindings, noBindings, false); 1123 return STOP; 1124} 1125 1126LocationHoleAttributeTest::LocationHoleAttributeTest (tcu::TestContext& testCtx, 1127 glu::RenderContext& renderCtx, 1128 const AttribType& type, 1129 int arraySize) 1130 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1131 , m_renderCtx (renderCtx) 1132 , m_type (type) 1133 , m_arraySize (arraySize) 1134{ 1135} 1136 1137tcu::TestCase::IterateResult LocationHoleAttributeTest::iterate (void) 1138{ 1139 const vector<Bind> noBindings; 1140 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 1141 const AttribType vec4("vec4", 1, GL_FLOAT_VEC4); 1142 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 1143 1144 vector<Attribute> attributes; 1145 int ndx; 1146 1147 attributes.push_back(Attribute(vec4, "a_0", 0)); 1148 1149 attributes.push_back(Attribute(m_type, "a_1", Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 1150 1151 ndx = 2; 1152 for (int loc = 1 + m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) 1153 { 1154 attributes.push_back(Attribute(vec4, "a_" + de::toString(ndx), loc)); 1155 ndx++; 1156 } 1157 1158 runTest(m_testCtx, m_renderCtx, attributes, noBindings, noBindings, noBindings, false); 1159 return STOP; 1160} 1161 1162MixedAttributeTest::MixedAttributeTest (tcu::TestContext& testCtx, 1163 glu::RenderContext& renderCtx, 1164 const AttribType& type, 1165 int arraySize) 1166 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1167 , m_renderCtx (renderCtx) 1168 , m_type (type) 1169 , m_arraySize (arraySize) 1170{ 1171} 1172 1173tcu::TestCase::IterateResult MixedAttributeTest::iterate (void) 1174{ 1175 const vector<Bind> noBindings; 1176 1177 vector<Bind> bindings; 1178 vector<Attribute> attributes; 1179 1180 attributes.push_back(Attribute(m_type, "a_0", 3, Cond::COND_ALWAYS, m_arraySize)); 1181 bindings.push_back(Bind("a_0", 4)); 1182 1183 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 1184 return STOP; 1185} 1186 1187MixedMaxAttributesTest::MixedMaxAttributesTest (tcu::TestContext& testCtx, 1188 glu::RenderContext& renderCtx, 1189 const AttribType& type, 1190 int arraySize) 1191 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1192 , m_renderCtx (renderCtx) 1193 , m_type (type) 1194 , m_arraySize (arraySize) 1195{ 1196} 1197 1198tcu::TestCase::IterateResult MixedMaxAttributesTest::iterate (void) 1199{ 1200 const vector<Bind> noBindings; 1201 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 1202 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 1203 1204 vector<Bind> bindings; 1205 vector<Attribute> attributes; 1206 int ndx = 0; 1207 1208 m_testCtx.getLog() << TestLog::Message << "GL_MAX_VERTEX_ATTRIBS: " << maxAttributes << TestLog::EndMessage; 1209 1210 for (int loc = maxAttributes - (arrayElementCount * m_type.getLocationSize()); loc >= 0; loc -= (arrayElementCount * m_type.getLocationSize())) 1211 { 1212 if ((ndx % 2) != 0) 1213 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx), loc, Cond::COND_ALWAYS, m_arraySize)); 1214 else 1215 { 1216 attributes.push_back(Attribute(m_type, "a_" + de::toString(ndx), Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 1217 bindings.push_back(Bind("a_" + de::toString(ndx), loc)); 1218 1219 } 1220 ndx++; 1221 } 1222 1223 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 1224 return STOP; 1225} 1226 1227MixedHoleAttributeTest::MixedHoleAttributeTest (tcu::TestContext& testCtx, 1228 glu::RenderContext& renderCtx, 1229 const AttribType& type, 1230 int arraySize) 1231 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1232 , m_renderCtx (renderCtx) 1233 , m_type (type) 1234 , m_arraySize (arraySize) 1235{ 1236} 1237 1238tcu::TestCase::IterateResult MixedHoleAttributeTest::iterate (void) 1239{ 1240 const vector<Bind> noBindings; 1241 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 1242 const AttribType vec4("vec4", 1, GL_FLOAT_VEC4); 1243 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 1244 1245 vector<Bind> bindings; 1246 vector<Attribute> attributes; 1247 int ndx; 1248 1249 attributes.push_back(Attribute(vec4, "a_0")); 1250 bindings.push_back(Bind("a_0", 0)); 1251 1252 attributes.push_back(Attribute(m_type, "a_1", Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 1253 1254 ndx = 2; 1255 for (int loc = 1 + m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) 1256 { 1257 if ((ndx % 2) != 0) 1258 attributes.push_back(Attribute(vec4, "a_" + de::toString(ndx), loc)); 1259 else 1260 { 1261 attributes.push_back(Attribute(vec4, "a_" + de::toString(ndx), loc)); 1262 bindings.push_back(Bind("a_" + de::toString(ndx), loc)); 1263 1264 } 1265 ndx++; 1266 } 1267 1268 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 1269 return STOP; 1270} 1271 1272BindRelinkAttributeTest::BindRelinkAttributeTest (tcu::TestContext& testCtx, 1273 glu::RenderContext& renderCtx) 1274 : TestCase (testCtx, "relink", "relink") 1275 , m_renderCtx (renderCtx) 1276{ 1277} 1278 1279tcu::TestCase::IterateResult BindRelinkAttributeTest::iterate (void) 1280{ 1281 const vector<Bind> noBindings; 1282 const AttribType vec4("vec4", 1, GL_FLOAT_VEC4); 1283 1284 vector<Attribute> attributes; 1285 vector<Bind> preLinkBindings; 1286 vector<Bind> postLinkBindings; 1287 1288 attributes.push_back(Attribute(vec4, "a_0")); 1289 attributes.push_back(Attribute(vec4, "a_1")); 1290 1291 preLinkBindings.push_back(Bind("a_0", 3)); 1292 preLinkBindings.push_back(Bind("a_0", 5)); 1293 1294 postLinkBindings.push_back(Bind("a_0", 6)); 1295 1296 runTest(m_testCtx, m_renderCtx, attributes, noBindings, preLinkBindings, postLinkBindings, true); 1297 return STOP; 1298} 1299 1300BindRelinkHoleAttributeTest::BindRelinkHoleAttributeTest (tcu::TestContext& testCtx, 1301 glu::RenderContext& renderCtx, 1302 const AttribType& type, 1303 int arraySize) 1304 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1305 , m_renderCtx (renderCtx) 1306 , m_type (type) 1307 , m_arraySize (arraySize) 1308{ 1309} 1310 1311tcu::TestCase::IterateResult BindRelinkHoleAttributeTest::iterate (void) 1312{ 1313 const vector<Bind> noBindings; 1314 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 1315 const AttribType vec4 ("vec4", 1, GL_FLOAT_VEC4); 1316 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 1317 1318 vector<Attribute> attributes; 1319 vector<Bind> preLinkBindings; 1320 vector<Bind> postLinkBindings; 1321 int ndx; 1322 1323 attributes.push_back(Attribute(vec4, "a_0")); 1324 preLinkBindings.push_back(Bind("a_0", 0)); 1325 1326 attributes.push_back(Attribute(m_type, "a_1", Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 1327 1328 ndx = 2; 1329 for (int loc = 1 + m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) 1330 { 1331 attributes.push_back(Attribute(vec4, "a_" + de::toString(ndx))); 1332 preLinkBindings.push_back(Bind("a_" + de::toString(ndx), loc)); 1333 1334 ndx++; 1335 } 1336 1337 postLinkBindings.push_back(Bind("a_2", 1)); 1338 1339 runTest(m_testCtx, m_renderCtx, attributes, noBindings, preLinkBindings, postLinkBindings, true); 1340 return STOP; 1341} 1342 1343MixedRelinkHoleAttributeTest::MixedRelinkHoleAttributeTest (tcu::TestContext& testCtx, 1344 glu::RenderContext& renderCtx, 1345 const AttribType& type, 1346 int arraySize) 1347 : TestCase (testCtx, generateTestName(type, arraySize).c_str(), generateTestName(type, arraySize).c_str()) 1348 , m_renderCtx (renderCtx) 1349 , m_type (type) 1350 , m_arraySize (arraySize) 1351{ 1352} 1353 1354tcu::TestCase::IterateResult MixedRelinkHoleAttributeTest::iterate (void) 1355{ 1356 const vector<Bind> noBindings; 1357 const deInt32 maxAttributes = getMaxAttributeLocations(m_renderCtx); 1358 const AttribType vec4 ("vec4", 1, GL_FLOAT_VEC4); 1359 const int arrayElementCount = (m_arraySize != Attribute::NOT_ARRAY ? m_arraySize : 1); 1360 1361 vector<Bind> preLinkBindings; 1362 vector<Bind> postLinkBindings; 1363 vector<Attribute> attributes; 1364 int ndx; 1365 1366 attributes.push_back(Attribute(vec4, "a_0")); 1367 preLinkBindings.push_back(Bind("a_0", 0)); 1368 1369 attributes.push_back(Attribute(m_type, "a_1", Attribute::LOC_UNDEF, Cond::COND_ALWAYS, m_arraySize)); 1370 1371 ndx = 2; 1372 for (int loc = 1 + m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) 1373 { 1374 if ((ndx % 2) != 0) 1375 attributes.push_back(Attribute(vec4, "a_" + de::toString(ndx), loc)); 1376 else 1377 { 1378 attributes.push_back(Attribute(vec4, "a_" + de::toString(ndx))); 1379 preLinkBindings.push_back(Bind("a_" + de::toString(ndx), loc)); 1380 1381 } 1382 ndx++; 1383 } 1384 1385 postLinkBindings.push_back(Bind("a_2", 1)); 1386 1387 runTest(m_testCtx, m_renderCtx, attributes, noBindings, preLinkBindings, postLinkBindings, true); 1388 return STOP; 1389} 1390 1391BindReattachAttributeTest::BindReattachAttributeTest (tcu::TestContext& testCtx, 1392 glu::RenderContext& renderCtx) 1393 : TestCase (testCtx, "reattach", "reattach") 1394 , m_renderCtx (renderCtx) 1395{ 1396} 1397 1398tcu::TestCase::IterateResult BindReattachAttributeTest::iterate (void) 1399{ 1400 const vector<Bind> noBindings; 1401 const AttribType vec4("vec4", 1, GL_FLOAT_VEC4); 1402 const AttribType vec2("vec2", 1, GL_FLOAT_VEC2); 1403 1404 vector<Bind> bindings; 1405 vector<Attribute> attributes; 1406 vector<Attribute> reattachAttributes; 1407 1408 attributes.push_back(Attribute(vec4, "a_0")); 1409 bindings.push_back(Bind("a_0", 1)); 1410 bindings.push_back(Bind("a_1", 1)); 1411 1412 reattachAttributes.push_back(Attribute(vec2, "a_1")); 1413 1414 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false, true, reattachAttributes); 1415 return STOP; 1416} 1417 1418PreAttachMixedAttributeTest::PreAttachMixedAttributeTest (tcu::TestContext& testCtx, 1419 glu::RenderContext& renderCtx) 1420 : TestCase (testCtx, "pre_attach", "pre_attach") 1421 , m_renderCtx (renderCtx) 1422{ 1423} 1424 1425tcu::TestCase::IterateResult PreAttachMixedAttributeTest::iterate (void) 1426{ 1427 const vector<Bind> noBindings; 1428 1429 vector<Attribute> attributes; 1430 vector<Bind> bindings; 1431 1432 attributes.push_back(Attribute(AttribType("vec4", 1, GL_FLOAT_VEC4), "a_0", 1)); 1433 bindings.push_back(Bind("a_0", 3)); 1434 1435 runTest(m_testCtx, m_renderCtx, attributes, bindings, noBindings, noBindings, false); 1436 return STOP; 1437} 1438 1439PreLinkMixedAttributeTest::PreLinkMixedAttributeTest (tcu::TestContext& testCtx, 1440 glu::RenderContext& renderCtx) 1441 : TestCase (testCtx, "pre_link", "pre_link") 1442 , m_renderCtx (renderCtx) 1443{ 1444} 1445 1446tcu::TestCase::IterateResult PreLinkMixedAttributeTest::iterate (void) 1447{ 1448 const vector<Bind> noBindings; 1449 1450 vector<Attribute> attributes; 1451 vector<Bind> bindings; 1452 1453 attributes.push_back(Attribute(AttribType("vec4", 1, GL_FLOAT_VEC4), "a_0", 1)); 1454 bindings.push_back(Bind("a_0", 3)); 1455 1456 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false); 1457 return STOP; 1458} 1459 1460PostLinkMixedAttributeTest::PostLinkMixedAttributeTest (tcu::TestContext& testCtx, 1461 glu::RenderContext& renderCtx) 1462 : TestCase (testCtx, "post_link", "post_link") 1463 , m_renderCtx (renderCtx) 1464{ 1465} 1466 1467tcu::TestCase::IterateResult PostLinkMixedAttributeTest::iterate (void) 1468{ 1469 const vector<Bind> noBindings; 1470 1471 vector<Attribute> attributes; 1472 vector<Bind> bindings; 1473 1474 attributes.push_back(Attribute(AttribType("vec4", 1, GL_FLOAT_VEC4), "a_0", 1)); 1475 bindings.push_back(Bind("a_0", 3)); 1476 1477 runTest(m_testCtx, m_renderCtx, attributes, noBindings, noBindings, bindings, false); 1478 return STOP; 1479} 1480 1481MixedReattachAttributeTest::MixedReattachAttributeTest (tcu::TestContext& testCtx, 1482 glu::RenderContext& renderCtx) 1483 : TestCase (testCtx, "reattach", "reattach") 1484 , m_renderCtx (renderCtx) 1485{ 1486} 1487 1488tcu::TestCase::IterateResult MixedReattachAttributeTest::iterate (void) 1489{ 1490 const vector<Bind> noBindings; 1491 const AttribType vec4("vec4", 1, GL_FLOAT_VEC4); 1492 const AttribType vec2("vec2", 1, GL_FLOAT_VEC2); 1493 1494 vector<Bind> bindings; 1495 vector<Attribute> attributes; 1496 vector<Attribute> reattachAttributes; 1497 1498 attributes.push_back(Attribute(vec4, "a_0", 2)); 1499 bindings.push_back(Bind("a_0", 1)); 1500 bindings.push_back(Bind("a_1", 1)); 1501 1502 reattachAttributes.push_back(Attribute(vec2, "a_1")); 1503 1504 runTest(m_testCtx, m_renderCtx, attributes, noBindings, bindings, noBindings, false, true, reattachAttributes); 1505 return STOP; 1506} 1507 1508MixedRelinkAttributeTest::MixedRelinkAttributeTest (tcu::TestContext& testCtx, 1509 glu::RenderContext& renderCtx) 1510 : TestCase (testCtx, "relink", "relink") 1511 , m_renderCtx (renderCtx) 1512{ 1513} 1514 1515tcu::TestCase::IterateResult MixedRelinkAttributeTest::iterate (void) 1516{ 1517 const vector<Bind> noBindings; 1518 const AttribType vec4("vec4", 1, GL_FLOAT_VEC4); 1519 1520 vector<Attribute> attributes; 1521 vector<Bind> preLinkBindings; 1522 vector<Bind> postLinkBindings; 1523 1524 attributes.push_back(Attribute(vec4, "a_0", 1)); 1525 attributes.push_back(Attribute(vec4, "a_1")); 1526 1527 preLinkBindings.push_back(Bind("a_0", 3)); 1528 preLinkBindings.push_back(Bind("a_0", 5)); 1529 1530 postLinkBindings.push_back(Bind("a_0", 6)); 1531 1532 runTest(m_testCtx, m_renderCtx, attributes, noBindings, preLinkBindings, postLinkBindings, true); 1533 return STOP; 1534} 1535 1536} // gls 1537} // deqp 1538