1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2014-2016 The Khronos Group Inc. 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 22 */ /*-------------------------------------------------------------------*/ 23 24#include "es31cProgramInterfaceQueryTests.hpp" 25#include "glwEnums.hpp" 26#include "glwFunctions.hpp" 27#include <cstdarg> 28#include <map> 29#include <set> 30 31namespace glcts 32{ 33 34using namespace glw; 35 36namespace 37{ 38 39class PIQBase : public glcts::SubcaseBase 40{ 41 42public: 43 virtual ~PIQBase() 44 { 45 } 46 47 virtual std::string PassCriteria() 48 { 49 return "All called functions return expected values."; 50 } 51 52 virtual std::string Purpose() 53 { 54 return "Verify that the set of tested functions glGetProgram* return\n" 55 "expected results when used to get data from program\n" 56 "made of " + 57 ShadersDesc() + "." + PurposeExt(); 58 } 59 60 virtual std::string Method() 61 { 62 return "Create a program using " + ShadersDesc() + 63 "\n" 64 "then use set of tested functions to get an information about it and\n" 65 "verify that information with the expected data" + 66 Expectations(); 67 } 68 69 virtual long Cleanup() 70 { 71 glUseProgram(0); 72 return NO_ERROR; 73 } 74 75 virtual long Setup() 76 { 77 return NO_ERROR; 78 } 79 80protected: 81 void LinkProgram(GLuint program) 82 { 83 glLinkProgram(program); 84 GLsizei length; 85 GLchar log[1024]; 86 glGetProgramInfoLog(program, sizeof(log), &length, log); 87 if (length > 1) 88 { 89 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n" 90 << log << tcu::TestLog::EndMessage; 91 } 92 } 93 94 GLuint CreateProgram(const char* src_vs, const char* src_fs, bool link) 95 { 96 const GLuint p = glCreateProgram(); 97 98 if (src_vs) 99 { 100 GLuint sh = glCreateShader(GL_VERTEX_SHADER); 101 glAttachShader(p, sh); 102 glDeleteShader(sh); 103 glShaderSource(sh, 1, &src_vs, NULL); 104 glCompileShader(sh); 105 } 106 if (src_fs) 107 { 108 GLuint sh = glCreateShader(GL_FRAGMENT_SHADER); 109 glAttachShader(p, sh); 110 glDeleteShader(sh); 111 glShaderSource(sh, 1, &src_fs, NULL); 112 glCompileShader(sh); 113 } 114 if (link) 115 { 116 LinkProgram(p); 117 } 118 return p; 119 } 120 121 virtual std::string ShadersDesc() 122 { 123 return ""; 124 } 125 126 virtual std::string Expectations() 127 { 128 return "."; 129 } 130 131 virtual std::string PurposeExt() 132 { 133 return ""; 134 } 135 136 virtual inline void ExpectError(GLenum expected, long& error) 137 { 138 if (error != NO_ERROR) 139 return; 140 GLenum tmp = glGetError(); 141 if (tmp == expected) 142 { 143 m_context.getTestContext().getLog() 144 << tcu::TestLog::Message << "Found expected error" << tcu::TestLog::EndMessage; 145 error = NO_ERROR; // Error is expected 146 } 147 else 148 { 149 error = ERROR; 150 m_context.getTestContext().getLog() << tcu::TestLog::Message << expected 151 << " error was expected, found: " << tmp << tcu::TestLog::EndMessage; 152 } 153 } 154 155 virtual inline void VerifyGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, int expected, 156 long& error) 157 { 158 GLint res; 159 glGetProgramInterfaceiv(program, programInterface, pname, &res); 160 if (res != expected) 161 { 162 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected " 163 << expected << tcu::TestLog::EndMessage; 164 error = ERROR; 165 } 166 } 167 168 virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, const std::string& name, 169 GLuint expected, long& error) 170 { 171 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str()); 172 if (res != expected) 173 { 174 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected " 175 << expected << tcu::TestLog::EndMessage; 176 error = ERROR; 177 } 178 } 179 180 virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, 181 std::map<std::string, GLuint>& indices, const std::string& name, 182 long& error) 183 { 184 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str()); 185 if (res == GL_INVALID_INDEX) 186 { 187 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res 188 << ", expected number other than -1" << tcu::TestLog::EndMessage; 189 error = ERROR; 190 return; 191 } 192 std::map<std::string, GLuint>::iterator it = indices.begin(); 193 while (it != indices.end()) 194 { 195 if (it->second == res) 196 { 197 m_context.getTestContext().getLog() 198 << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage; 199 error = ERROR; 200 return; 201 } 202 ++it; 203 } 204 indices[name] = res; 205 } 206 207 virtual inline void VerifyGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, 208 const std::string& expected, long& error) 209 { 210 GLchar name[1024] = { '\0' }; 211 GLsizei len; 212 glGetProgramResourceName(program, programInterface, index, 1024, &len, name); 213 if (len <= 0 || len > 1023 || name[len - 1] == '\0') 214 { 215 m_context.getTestContext().getLog() 216 << tcu::TestLog::Message 217 << "ERROR: Length in glGetProgramResourceName should not count null terminator!" 218 << tcu::TestLog::EndMessage; 219 error = ERROR; 220 } 221 else if (name != expected || name[len] != '\0') 222 { 223 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << name << ", expected " 224 << expected << tcu::TestLog::EndMessage; 225 error = ERROR; 226 } 227 } 228 229 virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface, 230 const std::string& name, GLint expected, long& error) 231 { 232 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str()); 233 if (res != expected) 234 { 235 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected " 236 << expected << tcu::TestLog::EndMessage; 237 error = ERROR; 238 } 239 } 240 241 virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface, 242 std::map<std::string, GLint>& locations, 243 const std::string& name, long& error) 244 { 245 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str()); 246 if (res < 0) 247 { 248 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res 249 << ", expected not less than 0" << tcu::TestLog::EndMessage; 250 error = ERROR; 251 return; 252 } 253 std::map<std::string, GLint>::iterator it = locations.begin(); 254 while (it != locations.end()) 255 { 256 if (it->second == res) 257 { 258 m_context.getTestContext().getLog() 259 << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage; 260 error = ERROR; 261 return; 262 } 263 ++it; 264 } 265 locations[name] = res; 266 } 267 268 virtual inline void VerifyGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, 269 GLsizei propCount, const GLenum props[], GLsizei expectedLength, 270 const GLint expected[], long& error) 271 { 272 const GLsizei bufSize = 1000; 273 GLsizei length; 274 GLint params[bufSize]; 275 glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, &length, params); 276 if (length != expectedLength || length <= 0) 277 { 278 error = ERROR; 279 m_context.getTestContext().getLog() 280 << tcu::TestLog::Message << "ERROR: Got length " << length << ", expected " << expectedLength 281 << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index 282 << tcu::TestLog::EndMessage; 283 return; 284 } 285 for (int i = 0; i < length; ++i) 286 { 287 if (params[i] != expected[i]) 288 { 289 error = ERROR; 290 m_context.getTestContext().getLog() 291 << tcu::TestLog::Message << "ERROR: Got " << params[i] << ", expected " << expected[i] 292 << " at: " << i << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index 293 << tcu::TestLog::EndMessage; 294 } 295 } 296 } 297 298 virtual inline GLint GetProgramivRetValue(GLuint program, GLenum pname) 299 { 300 GLint ret; 301 glGetProgramiv(program, pname, &ret); 302 return ret; 303 } 304 305 static const GLenum interfaces[]; 306}; 307 308const GLenum PIQBase::interfaces[] = { GL_PROGRAM_INPUT, 309 GL_PROGRAM_OUTPUT, 310 GL_UNIFORM, 311 GL_UNIFORM_BLOCK, 312 GL_BUFFER_VARIABLE, 313 GL_SHADER_STORAGE_BLOCK, 314 GL_ATOMIC_COUNTER_BUFFER, 315 GL_TRANSFORM_FEEDBACK_VARYING }; 316 317class NoShaders : public PIQBase 318{ 319 320 virtual std::string Title() 321 { 322 return "No Shaders Test"; 323 } 324 325 virtual std::string ShadersDesc() 326 { 327 return "no shaders"; 328 } 329 330 virtual long Run() 331 { 332 const GLuint program = glCreateProgram(); 333 334 long error = NO_ERROR; 335 int size = sizeof(PIQBase::interfaces) / sizeof(PIQBase::interfaces[0]); 336 337 for (int i = 0; i < size; ++i) 338 { 339 VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_ACTIVE_RESOURCES, 0, error); 340 if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER) 341 continue; 342 VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_MAX_NAME_LENGTH, 0, error); 343 } 344 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error); 345 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error); 346 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error); 347 348 for (int i = 0; i < size; ++i) 349 { 350 if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER) 351 continue; 352 VerifyGetProgramResourceIndex(program, PIQBase::interfaces[i], "", GL_INVALID_INDEX, error); 353 } 354 355 // can't test GetProgramResourceLocation* here since program has to be linked 356 // can't test GetProgramResourceiv, need valid index 357 358 glDeleteProgram(program); 359 return error; 360 } 361}; 362 363class SimpleShaders : public PIQBase 364{ 365 366public: 367 virtual std::string Title() 368 { 369 return "Simple Shaders Test"; 370 } 371 372 virtual std::string ShadersDesc() 373 { 374 return "fallthrough fragment and vertex shaders"; 375 } 376 377 virtual std::string VertexShader() 378 { 379 return "#version 310 es \n" 380 "in vec4 position; \n" 381 "void main(void) \n" 382 "{ \n" 383 " gl_Position = position; \n" 384 "}"; 385 } 386 387 virtual std::string FragmentShader() 388 { 389 return "#version 310 es \n" 390 "out mediump vec4 color; \n" 391 "void main() { \n" 392 " color = vec4(0, 1, 0, 1); \n" 393 "}"; 394 } 395 396 virtual long Run() 397 { 398 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 399 glBindAttribLocation(program, 0, "position"); 400 glLinkProgram(program); 401 402 long error = NO_ERROR; 403 404 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error); 405 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error); 406 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error); 407 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error); 408 409 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error); 410 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error); 411 412 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error); 413 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error); 414 415 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error); 416 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error); 417 418 GLenum props[] = { GL_NAME_LENGTH, 419 GL_TYPE, 420 GL_ARRAY_SIZE, 421 GL_REFERENCED_BY_COMPUTE_SHADER, 422 GL_REFERENCED_BY_FRAGMENT_SHADER, 423 GL_REFERENCED_BY_VERTEX_SHADER, 424 GL_LOCATION }; 425 GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 }; 426 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 7, props, 7, expected, error); 427 428 GLenum props2[] = { GL_NAME_LENGTH, 429 GL_TYPE, 430 GL_ARRAY_SIZE, 431 GL_REFERENCED_BY_COMPUTE_SHADER, 432 GL_REFERENCED_BY_FRAGMENT_SHADER, 433 GL_REFERENCED_BY_VERTEX_SHADER, 434 GL_LOCATION }; 435 GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 }; 436 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error); 437 438 glDeleteProgram(program); 439 return error; 440 } 441}; 442 443class ComputeShaderTest : public PIQBase 444{ 445public: 446 virtual std::string Title() 447 { 448 return "Compute Shader Test"; 449 } 450 451 virtual std::string ShadersDesc() 452 { 453 return "compute shader"; 454 } 455 456 virtual std::string ComputeShader() 457 { 458 return "layout(local_size_x = 1, local_size_y = 1) in; \n" 459 "layout(std430) buffer Output { \n" 460 " mediump vec4 data[]; \n" 461 "} g_out; \n" 462 "" 463 "void main() { \n" 464 " g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0); \n" 465 " g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0); \n" 466 "}"; 467 } 468 469 GLuint CreateComputeProgram(const std::string& cs) 470 { 471 const GLuint p = glCreateProgram(); 472 473 const char* const kGLSLVer = "#version 310 es\n"; 474 475 if (!cs.empty()) 476 { 477 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 478 glAttachShader(p, sh); 479 glDeleteShader(sh); 480 const char* const src[2] = { kGLSLVer, cs.c_str() }; 481 glShaderSource(sh, 2, src, NULL); 482 glCompileShader(sh); 483 } 484 485 return p; 486 } 487 488 bool CheckProgram(GLuint program, bool* compile_error = NULL) 489 { 490 GLint compile_status = GL_TRUE; 491 GLint status; 492 glGetProgramiv(program, GL_LINK_STATUS, &status); 493 494 if (status == GL_FALSE) 495 { 496 GLint attached_shaders; 497 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); 498 499 if (attached_shaders > 0) 500 { 501 std::vector<GLuint> shaders(attached_shaders); 502 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]); 503 504 for (GLint i = 0; i < attached_shaders; ++i) 505 { 506 GLenum type; 507 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type)); 508 switch (type) 509 { 510 case GL_VERTEX_SHADER: 511 m_context.getTestContext().getLog() 512 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage; 513 break; 514 case GL_TESS_CONTROL_SHADER: 515 m_context.getTestContext().getLog() 516 << tcu::TestLog::Message << "*** Tessellation Control Shader ***" 517 << tcu::TestLog::EndMessage; 518 break; 519 case GL_TESS_EVALUATION_SHADER: 520 m_context.getTestContext().getLog() 521 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***" 522 << tcu::TestLog::EndMessage; 523 break; 524 case GL_GEOMETRY_SHADER: 525 m_context.getTestContext().getLog() 526 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage; 527 break; 528 case GL_FRAGMENT_SHADER: 529 m_context.getTestContext().getLog() 530 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage; 531 break; 532 case GL_COMPUTE_SHADER: 533 m_context.getTestContext().getLog() 534 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage; 535 break; 536 default: 537 m_context.getTestContext().getLog() 538 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage; 539 } 540 541 GLint res; 542 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res); 543 if (res != GL_TRUE) 544 compile_status = res; 545 546 // shader source 547 GLint length; 548 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length); 549 if (length > 0) 550 { 551 std::vector<GLchar> source(length); 552 glGetShaderSource(shaders[i], length, NULL, &source[0]); 553 m_context.getTestContext().getLog() 554 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage; 555 } 556 557 // shader info log 558 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length); 559 if (length > 0) 560 { 561 std::vector<GLchar> log(length); 562 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]); 563 m_context.getTestContext().getLog() 564 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 565 } 566 } 567 } 568 569 // program info log 570 GLint length; 571 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 572 if (length > 0) 573 { 574 std::vector<GLchar> log(length); 575 glGetProgramInfoLog(program, length, NULL, &log[0]); 576 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 577 } 578 } 579 580 if (compile_error) 581 *compile_error = (compile_status == GL_TRUE ? false : true); 582 if (compile_status != GL_TRUE) 583 return false; 584 return status == GL_TRUE ? true : false; 585 } 586 587 virtual void inline VerifyCompute(GLuint program, long& error) 588 { 589 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error); 590 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error); 591 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error); 592 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error); 593 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error); 594 595 std::map<std::string, GLuint> indicesSSB; 596 std::map<std::string, GLuint> indicesBV; 597 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error); 598 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error); 599 600 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error); 601 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error); 602 603 GLenum props3[] = { GL_NAME_LENGTH, 604 GL_BUFFER_BINDING, 605 GL_NUM_ACTIVE_VARIABLES, 606 GL_REFERENCED_BY_COMPUTE_SHADER, 607 GL_REFERENCED_BY_FRAGMENT_SHADER, 608 GL_REFERENCED_BY_VERTEX_SHADER, 609 GL_ACTIVE_VARIABLES }; 610 GLint expected3[] = { 7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"]) }; 611 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3, 612 error); 613 614 GLenum props4[] = { GL_NAME_LENGTH, 615 GL_TYPE, 616 GL_ARRAY_SIZE, 617 GL_BLOCK_INDEX, 618 GL_IS_ROW_MAJOR, 619 GL_REFERENCED_BY_COMPUTE_SHADER, 620 GL_REFERENCED_BY_FRAGMENT_SHADER, 621 GL_REFERENCED_BY_VERTEX_SHADER, 622 GL_TOP_LEVEL_ARRAY_SIZE }; 623 GLint expected4[] = { 15, 35666, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1 }; 624 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4, 625 error); 626 } 627 628 virtual long Run() 629 { 630 GLuint program = CreateComputeProgram(ComputeShader()); 631 glLinkProgram(program); 632 if (!CheckProgram(program)) 633 { 634 glDeleteProgram(program); 635 return ERROR; 636 } 637 glUseProgram(program); 638 639 long error = NO_ERROR; 640 641 VerifyCompute(program, error); 642 643 glDeleteProgram(program); 644 return error; 645 } 646}; 647 648class InputTypes : public SimpleShaders 649{ 650 virtual std::string Title() 651 { 652 return "Input Types Test"; 653 } 654 655 virtual std::string ShadersDesc() 656 { 657 return "vertex shader with different `in` types and a fallthrough fragment shader"; 658 } 659 660 virtual std::string VertexShader() 661 { 662 return "#version 310 es \n" 663 "in mat4 a; \n" 664 "in vec4 b; \n" 665 "in float c; \n" 666 "in mat2x3 d; \n" 667 "in vec2 e; \n" 668 "in uint f; \n" 669 "in vec3 g; \n" 670 "in int h; \n" 671 "void main(void) \n" 672 "{ \n" 673 " vec4 pos; \n" 674 " pos.w = float(h) + g.x + g.y + d[1].y; \n" 675 " pos.y = float(b.x) * c + c + d[0][0]; \n" 676 " pos.x = a[0].x + a[1].y + a[2].z + a[3].w; \n" 677 " pos.z = d[0][1] + float(e.x) * float(f) + d[1][0]; \n" 678 " gl_Position = pos; \n" 679 "}"; 680 } 681 682 virtual long Run() 683 { 684 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 685 glBindAttribLocation(program, 0, "a"); 686 glBindAttribLocation(program, 4, "b"); 687 glBindAttribLocation(program, 5, "c"); 688 glBindAttribLocation(program, 7, "d"); 689 glBindAttribLocation(program, 11, "e"); 690 glBindAttribLocation(program, 12, "f"); 691 glBindAttribLocation(program, 13, "g"); 692 glBindAttribLocation(program, 15, "h"); 693 LinkProgram(program); 694 695 long error = NO_ERROR; 696 697 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error); 698 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error); 699 700 std::map<std::string, GLuint> indices; 701 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error); 702 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error); 703 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error); 704 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error); 705 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error); 706 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error); 707 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error); 708 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error); 709 710 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error); 711 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error); 712 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error); 713 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error); 714 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error); 715 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error); 716 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error); 717 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error); 718 719 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error); 720 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error); 721 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error); 722 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error); 723 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error); 724 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error); 725 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error); 726 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error); 727 728 GLenum props[] = { 729 GL_NAME_LENGTH, 730 GL_TYPE, 731 GL_ARRAY_SIZE, 732 GL_REFERENCED_BY_COMPUTE_SHADER, 733 GL_REFERENCED_BY_FRAGMENT_SHADER, 734 GL_REFERENCED_BY_VERTEX_SHADER, 735 GL_LOCATION, 736 }; 737 GLint expected[] = { 2, 35676, 1, 0, 0, 1, 0 }; 738 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error); 739 GLint expected2[] = { 2, 35666, 1, 0, 0, 1, 4 }; 740 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error); 741 GLint expected3[] = { 2, 5126, 1, 0, 0, 1, 5 }; 742 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error); 743 GLint expected4[] = { 2, 35685, 1, 0, 0, 1, 7 }; 744 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error); 745 GLint expected5[] = { 2, 35664, 1, 0, 0, 1, 11 }; 746 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error); 747 GLint expected6[] = { 2, 5125, 1, 0, 0, 1, 12 }; 748 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error); 749 GLint expected7[] = { 2, 35665, 1, 0, 0, 1, 13 }; 750 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error); 751 GLint expected8[] = { 2, 5124, 1, 0, 0, 1, 15 }; 752 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error); 753 754 glDeleteProgram(program); 755 return error; 756 } 757}; 758 759class InputBuiltIn : public SimpleShaders 760{ 761 762 virtual std::string Title() 763 { 764 return "Input Built-ins Test"; 765 } 766 767 virtual std::string ShadersDesc() 768 { 769 return "vertex shader using built-in variables and a fallthrough fragment shader"; 770 } 771 772 virtual std::string Expectations() 773 { 774 return ".\n\n In this case we ask for information about built-in variables for the input interface."; 775 } 776 777 virtual std::string VertexShader() 778 { 779 return "#version 310 es \n" 780 "void main(void) \n" 781 "{ \n" 782 " gl_Position = (float(gl_VertexID) + float(gl_InstanceID)) * vec4(0.1); \n" 783 "}"; 784 } 785 786 virtual long Run() 787 { 788 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 789 LinkProgram(program); 790 791 long error = NO_ERROR; 792 793 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 2, error); 794 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 14, error); 795 796 std::map<std::string, GLuint> indices; 797 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_VertexID", error); 798 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_InstanceID", error); 799 800 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], "gl_VertexID", error); 801 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], "gl_InstanceID", error); 802 803 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_VertexID", -1, error); 804 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_InstanceID", -1, error); 805 806 GLenum props[] = { GL_NAME_LENGTH, 807 GL_TYPE, 808 GL_ARRAY_SIZE, 809 GL_REFERENCED_BY_COMPUTE_SHADER, 810 GL_REFERENCED_BY_FRAGMENT_SHADER, 811 GL_REFERENCED_BY_VERTEX_SHADER, 812 GL_LOCATION }; 813 GLint expected[] = { 12, 5124, 1, 0, 0, 1, -1 }; 814 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], 7, props, 7, expected, error); 815 GLint expected2[] = { 14, 5124, 1, 0, 0, 1, -1 }; 816 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], 7, props, 7, expected2, error); 817 818 glDeleteProgram(program); 819 return error; 820 } 821}; 822 823class InputLayout : public SimpleShaders 824{ 825 virtual std::string Title() 826 { 827 return "Input Layout Test"; 828 } 829 830 virtual std::string ShadersDesc() 831 { 832 return "vertex shader with different `in` variables locations set through layout and a fallthrough fragment " 833 "shader"; 834 } 835 836 virtual std::string VertexShader() 837 { 838 return "#version 310 es \n" 839 "layout(location = 4) in vec4 b; \n" 840 "layout(location = 7) in mat2x3 d; \n" 841 "layout(location = 5) in float c; \n" 842 "layout(location = 12) in uint f; \n" 843 "layout(location = 13) in vec3 g; \n" 844 "layout(location = 0) in mat4 a; \n" 845 "layout(location = 15) in int h; \n" 846 "layout(location = 11) in vec2 e; \n" 847 "void main(void) \n" 848 "{ \n" 849 " vec4 pos; \n" 850 " pos.w = float(h) + g.x + g.y + d[1][1]; \n" 851 " pos.y = float(b.x) * c + c + d[0][0]; \n" 852 " pos.x = a[0].x + a[1].y + a[2].z + a[3].w; \n" 853 " pos.z = d[0][1] + float(e.x) * float(f) + d[1][0]; \n" 854 " gl_Position = pos; \n" 855 "}"; 856 } 857 858 virtual long Run() 859 { 860 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 861 LinkProgram(program); 862 863 long error = NO_ERROR; 864 865 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error); 866 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error); 867 868 std::map<std::string, GLuint> indices; 869 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error); 870 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error); 871 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error); 872 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error); 873 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error); 874 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error); 875 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error); 876 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error); 877 878 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error); 879 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error); 880 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error); 881 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error); 882 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error); 883 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error); 884 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error); 885 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error); 886 887 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error); 888 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error); 889 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error); 890 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error); 891 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error); 892 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error); 893 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error); 894 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error); 895 896 GLenum props[] = { GL_NAME_LENGTH, 897 GL_TYPE, 898 GL_ARRAY_SIZE, 899 GL_REFERENCED_BY_COMPUTE_SHADER, 900 GL_REFERENCED_BY_FRAGMENT_SHADER, 901 GL_REFERENCED_BY_VERTEX_SHADER, 902 GL_LOCATION }; 903 GLint expected[] = { 2, 35676, 1, 0, 0, 1, 0 }; 904 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error); 905 GLint expected2[] = { 2, 35666, 1, 0, 0, 1, 4 }; 906 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error); 907 GLint expected3[] = { 2, 5126, 1, 0, 0, 1, 5 }; 908 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error); 909 GLint expected4[] = { 2, 35685, 1, 0, 0, 1, 7 }; 910 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error); 911 GLint expected5[] = { 2, 35664, 1, 0, 0, 1, 11 }; 912 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error); 913 GLint expected6[] = { 2, 5125, 1, 0, 0, 1, 12 }; 914 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error); 915 GLint expected7[] = { 2, 35665, 1, 0, 0, 1, 13 }; 916 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error); 917 GLint expected8[] = { 2, 5124, 1, 0, 0, 1, 15 }; 918 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error); 919 920 glDeleteProgram(program); 921 return error; 922 } 923}; 924 925class OutputLayout : public SimpleShaders 926{ 927 virtual std::string Title() 928 { 929 return "Output Layout Test"; 930 } 931 932 virtual std::string ShadersDesc() 933 { 934 return "fragment shader with different `out` variables locations set through layout and a fallthrough vertex " 935 "shader"; 936 } 937 938 virtual std::string FragmentShader() 939 { 940 return "#version 310 es \n" 941 "layout(location = 2) out uint b; \n" 942 "layout(location = 3) out mediump vec2 e; \n" 943 "layout(location = 0) out mediump vec3 a[2]; \n" 944 "void main() { \n" 945 " b = 12u; \n" 946 " e = vec2(0, 1); \n" 947 " a[1] = vec3(0, 1, 0); \n" 948 " a[0] = vec3(0, 1, 0); \n" 949 "}"; 950 } 951 952 virtual long Run() 953 { 954 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 955 glBindAttribLocation(program, 0, "position"); 956 LinkProgram(program); 957 958 long error = NO_ERROR; 959 960 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 3, error); 961 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error); 962 963 std::map<std::string, GLuint> indices; 964 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error); 965 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error); 966 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error); 967 968 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error); 969 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error); 970 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error); 971 972 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error); 973 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error); 974 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error); 975 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error); 976 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 3, error); 977 978 GLenum props[] = { GL_NAME_LENGTH, 979 GL_TYPE, 980 GL_ARRAY_SIZE, 981 GL_REFERENCED_BY_COMPUTE_SHADER, 982 GL_REFERENCED_BY_FRAGMENT_SHADER, 983 GL_REFERENCED_BY_VERTEX_SHADER, 984 GL_LOCATION }; 985 GLint expected_a[] = { 5, 35665, 2, 0, 1, 0, 0 }; 986 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 7, props, 7, expected_a, error); 987 GLint expected_b[] = { 2, 5125, 1, 0, 1, 0, 2 }; 988 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 7, props, 7, expected_b, error); 989 GLint expected_e[] = { 2, 35664, 1, 0, 1, 0, 3 }; 990 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 7, props, 7, expected_e, error); 991 992 glDeleteProgram(program); 993 return error; 994 } 995}; 996 997class UniformSimple : public PIQBase 998{ 999 virtual std::string Title() 1000 { 1001 return "Uniform Simple Test"; 1002 } 1003 1004 virtual std::string ShadersDesc() 1005 { 1006 return "fallthrough fragment and vertex shaders with uniforms used"; 1007 } 1008 1009 virtual std::string PurposeExt() 1010 { 1011 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param."; 1012 } 1013 1014 virtual std::string VertexShader() 1015 { 1016 return "#version 310 es \n" 1017 "in vec4 position; \n" 1018 "uniform mediump vec4 repos; \n" 1019 "void main(void) \n" 1020 "{ \n" 1021 " gl_Position = position + repos; \n" 1022 "}"; 1023 } 1024 1025 virtual std::string FragmentShader() 1026 { 1027 return "#version 310 es \n" 1028 "uniform mediump vec4 recolor; \n" 1029 "out mediump vec4 color; \n" 1030 "void main() { \n" 1031 " color = vec4(0, 1, 0, 1) + recolor; \n" 1032 "}"; 1033 } 1034 1035 virtual long Run() 1036 { 1037 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 1038 glBindAttribLocation(program, 0, "position"); 1039 LinkProgram(program); 1040 1041 long error = NO_ERROR; 1042 1043 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1044 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error); 1045 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 8, error); 1046 1047 std::map<std::string, GLuint> indices; 1048 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "repos", error); 1049 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "recolor", error); 1050 1051 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["repos"], "repos", error); 1052 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["recolor"], "recolor", error); 1053 1054 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "repos", glGetUniformLocation(program, "repos"), error); 1055 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "recolor", glGetUniformLocation(program, "recolor"), 1056 error); 1057 1058 GLenum props[] = { GL_NAME_LENGTH, 1059 GL_TYPE, 1060 GL_ARRAY_SIZE, 1061 GL_OFFSET, 1062 GL_BLOCK_INDEX, 1063 GL_ARRAY_STRIDE, 1064 GL_MATRIX_STRIDE, 1065 GL_IS_ROW_MAJOR, 1066 GL_ATOMIC_COUNTER_BUFFER_INDEX, 1067 GL_REFERENCED_BY_COMPUTE_SHADER, 1068 GL_REFERENCED_BY_FRAGMENT_SHADER, 1069 GL_REFERENCED_BY_VERTEX_SHADER, 1070 GL_LOCATION }; 1071 GLint expected[] = { 6, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "repos") }; 1072 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 13, props, 13, expected, error); 1073 1074 GLint expected2[] = { 8, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "recolor") }; 1075 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 13, props, 13, expected2, error); 1076 1077 glDeleteProgram(program); 1078 return error; 1079 } 1080}; 1081 1082class UniformTypes : public PIQBase 1083{ 1084 virtual std::string Title() 1085 { 1086 return "Uniform Types Test"; 1087 } 1088 1089 virtual std::string ShadersDesc() 1090 { 1091 return "fallthrough fragment and vertex shaders with different uniform types used"; 1092 } 1093 1094 virtual std::string PurposeExt() 1095 { 1096 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n"; 1097 } 1098 1099 virtual std::string VertexShader() 1100 { 1101 return "#version 310 es \n" 1102 "in vec4 position; \n" 1103 "uniform mediump vec4 a; \n" 1104 "uniform ivec3 b; \n" 1105 "uniform uvec2 c[3]; \n" 1106 "uniform mediump mat2 g[8]; \n" 1107 "uniform mediump mat3x2 i; \n" 1108 "void main(void) \n" 1109 "{ \n" 1110 " float tmp; \n" 1111 " tmp = g[0][1][1] * g[1][0][0] + g[2][1][0] - g[3][0][1]; \n" 1112 " tmp = tmp + g[4][0][0] * g[5][1][0] - g[6][1][1] + g[7][0][1]; \n" 1113 " tmp = tmp + a.z + +float(b.y) + float(c[0].x) - float(c[1].x) * float(c[2].y); \n" 1114 " tmp = tmp + i[1][1]; \n" 1115 " gl_Position = position * tmp; \n" 1116 "}"; 1117 } 1118 1119 virtual std::string FragmentShader() 1120 { 1121 return "#version 310 es \n" 1122 "struct U { \n" 1123 " bool a[3]; \n" 1124 " mediump vec4 b; \n" 1125 " mediump mat3 c; \n" 1126 " mediump float d[2]; \n" 1127 "}; \n" 1128 "struct UU { \n" 1129 " U a; \n" 1130 " U b[2]; \n" 1131 " uvec2 c; \n" 1132 "}; \n" 1133 "uniform mediump mat4 d; \n" 1134 "uniform mediump mat3 e; \n" 1135 "uniform mediump float h; \n" 1136 "uniform int f; \n" 1137 "uniform U j; \n" 1138 "uniform UU k; \n" 1139 "uniform UU l[3]; \n" 1140 "out mediump vec4 color; \n" 1141 "void main() { \n" 1142 " mediump float tmp; \n" 1143 " tmp = h + float(f) + e[2][2]; \n" 1144 " tmp = tmp + d[0][0] + j.b.x; \n" 1145 " tmp = tmp + k.b[0].c[0][0]; \n" 1146 " tmp = tmp + l[2].a.c[0][1]; \n" 1147 " tmp = tmp + l[2].b[1].d[0]; \n" 1148 " tmp = tmp + float(l[0].c.x); \n" 1149 " color = vec4(0, 1, 0, 1) * tmp; \n" 1150 "}"; 1151 } 1152 1153 virtual long Run() 1154 { 1155 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 1156 glBindAttribLocation(program, 0, "position"); 1157 LinkProgram(program); 1158 1159 long error = NO_ERROR; 1160 1161 // only active structure members 1162 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1163 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error); 1164 // l[2].b[1].d[0] and \0 1165 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error); 1166 1167 std::map<std::string, GLuint> indices; 1168 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error); 1169 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error); 1170 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error); 1171 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error); 1172 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error); 1173 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error); 1174 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error); 1175 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error); 1176 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error); 1177 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error); 1178 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error); 1179 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error); 1180 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error); 1181 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error); 1182 1183 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error); 1184 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error); 1185 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error); 1186 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error); 1187 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error); 1188 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error); 1189 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error); 1190 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error); 1191 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error); 1192 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error); 1193 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error); 1194 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error); 1195 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error); 1196 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error); 1197 1198 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error); 1199 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error); 1200 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error); 1201 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error); 1202 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error); 1203 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error); 1204 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error); 1205 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error); 1206 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error); 1207 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error); 1208 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"), 1209 error); 1210 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error); 1211 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]", 1212 glGetUniformLocation(program, "l[2].b[1].d[0]"), error); 1213 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"), 1214 error); 1215 1216 GLenum props[] = { GL_NAME_LENGTH, 1217 GL_TYPE, 1218 GL_ARRAY_SIZE, 1219 GL_OFFSET, 1220 GL_BLOCK_INDEX, 1221 GL_ARRAY_STRIDE, 1222 GL_MATRIX_STRIDE, 1223 GL_IS_ROW_MAJOR, 1224 GL_ATOMIC_COUNTER_BUFFER_INDEX, 1225 GL_REFERENCED_BY_COMPUTE_SHADER, 1226 GL_REFERENCED_BY_FRAGMENT_SHADER, 1227 GL_REFERENCED_BY_VERTEX_SHADER, 1228 GL_LOCATION }; 1229 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a") }; 1230 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 13, props, 13, expected, error); 1231 GLint expected2[] = { 2, 35668, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "b") }; 1232 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 13, props, 13, expected2, error); 1233 GLint expected3[] = { 5, 36294, 3, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "c") }; 1234 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 13, props, 13, expected3, error); 1235 GLint expected4[] = { 2, 35676, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "d") }; 1236 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 13, props, 13, expected4, error); 1237 GLint expected5[] = { 2, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "e") }; 1238 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 13, props, 13, expected5, error); 1239 GLint expected6[] = { 2, 5124, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "f") }; 1240 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 13, props, 13, expected6, error); 1241 GLint expected7[] = { 5, 35674, 8, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "g") }; 1242 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 13, props, 13, expected7, error); 1243 GLint expected8[] = { 2, 5126, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "h") }; 1244 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 13, props, 13, expected8, error); 1245 GLint expected9[] = { 2, 35687, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "i") }; 1246 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 13, props, 13, expected9, error); 1247 GLint expected10[] = { 4, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "j.b") }; 1248 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 13, props, 13, expected10, error); 1249 GLint expected11[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "k.b[0].c") }; 1250 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 13, props, 13, expected11, error); 1251 GLint expected12[] = { 7, 36294, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[0].c") }; 1252 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 13, props, 13, expected12, error); 1253 GLint expected13[] = { 1254 15, 5126, 2, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].b[1].d[0]") 1255 }; 1256 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 13, props, 13, expected13, error); 1257 GLint expected14[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].a.c") }; 1258 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 13, props, 13, expected14, error); 1259 1260 glDeleteProgram(program); 1261 return error; 1262 } 1263}; 1264 1265class UniformBlockTypes : public PIQBase 1266{ 1267 virtual std::string Title() 1268 { 1269 return "Uniform Block Types Test"; 1270 } 1271 1272 virtual std::string ShadersDesc() 1273 { 1274 return "fallthrough fragment and vertex shaders with different types of uniform blocks used"; 1275 } 1276 1277 virtual std::string PurposeExt() 1278 { 1279 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n"; 1280 } 1281 1282 virtual std::string VertexShader() 1283 { 1284 return "#version 310 es \n" 1285 "in vec4 position; \n" 1286 "" 1287 "uniform SimpleBlock { \n" 1288 " mediump mat3x2 a; \n" 1289 " mediump mat4 b; \n" 1290 " vec4 c; \n" 1291 "}; \n" 1292 "" 1293 "uniform NotSoSimpleBlockk { \n" 1294 " ivec2 a[4]; \n" 1295 " mediump mat3 b[2]; \n" 1296 " mediump mat2 c; \n" 1297 "} d; \n" 1298 "" 1299 "void main(void) \n" 1300 "{ \n" 1301 " mediump float tmp; \n" 1302 " tmp = a[0][1] * b[1][2] * c.x; \n" 1303 " tmp = tmp + float(d.a[2].y) + d.b[0][1][1] + d.c[1][1]; \n" 1304 " gl_Position = position * tmp; \n" 1305 "}"; 1306 } 1307 1308 virtual std::string FragmentShader() 1309 { 1310 return "#version 310 es \n" 1311 "struct U { \n" 1312 " bool a[3]; \n" 1313 " mediump vec4 b; \n" 1314 " mediump mat3 c; \n" 1315 " mediump float d[2]; \n" 1316 "}; \n" 1317 "struct UU { \n" 1318 " U a; \n" 1319 " U b[2]; \n" 1320 " uvec2 c; \n" 1321 "}; \n" 1322 "" 1323 "uniform TrickyBlock { \n" 1324 " UU a[3]; \n" 1325 " mediump mat4 b; \n" 1326 " uint c; \n" 1327 "} e[2]; \n" 1328 "" 1329 "out mediump vec4 color; \n" 1330 "void main() { \n" 1331 " mediump float tmp; \n" 1332 " tmp = e[0].a[2].b[0].d[1] * float(e[1].c); \n" 1333 " color = vec4(0, 1, 0, 1) * tmp; \n" 1334 "}"; 1335 } 1336 1337 virtual long Run() 1338 { 1339 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 1340 glBindAttribLocation(program, 0, "position"); 1341 LinkProgram(program); 1342 1343 long error = NO_ERROR; 1344 1345 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1346 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error); 1347 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error); 1348 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error); 1349 1350 std::map<std::string, GLuint> indicesUB; 1351 std::map<std::string, GLuint> indicesU; 1352 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error); 1353 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error); 1354 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error); 1355 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error); 1356 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error); 1357 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error); 1358 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error); 1359 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error); 1360 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error); 1361 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error); 1362 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error); 1363 1364 glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0); 1365 glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2); 1366 glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3); 1367 glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4); 1368 1369 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error); 1370 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk", 1371 error); 1372 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error); 1373 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error); 1374 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error); 1375 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error); 1376 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error); 1377 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]", 1378 error); 1379 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c", 1380 error); 1381 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]", 1382 error); 1383 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 1384 "TrickyBlock.a[2].b[0].d[0]", error); 1385 1386 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error); 1387 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error); 1388 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error); 1389 1390 GLenum props[] = { 1391 GL_NAME_LENGTH, 1392 GL_BUFFER_BINDING, 1393 GL_REFERENCED_BY_COMPUTE_SHADER, 1394 GL_REFERENCED_BY_FRAGMENT_SHADER, 1395 GL_REFERENCED_BY_VERTEX_SHADER, 1396 GL_BUFFER_DATA_SIZE, 1397 }; 1398 GLint size; 1399 glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size); 1400 GLint expected[] = { 12, 0, 0, 0, 1, size }; 1401 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 6, props, 6, expected, error); 1402 glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size); 1403 GLint expected2[] = { 18, 2, 0, 0, 1, size }; 1404 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 6, props, 6, expected2, 1405 error); 1406 glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size); 1407 GLint expected3[] = { 15, 3, 0, 1, 0, size }; 1408 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 6, props, 6, expected3, error); 1409 GLint expected4[] = { 15, 4, 0, 1, 0, size }; 1410 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 6, props, 6, expected4, 1411 error); 1412 1413 GLenum props2[] = { GL_NAME_LENGTH, 1414 GL_TYPE, 1415 GL_ARRAY_SIZE, 1416 GL_BLOCK_INDEX, 1417 GL_ARRAY_STRIDE, 1418 GL_IS_ROW_MAJOR, 1419 GL_ATOMIC_COUNTER_BUFFER_INDEX, 1420 GL_REFERENCED_BY_COMPUTE_SHADER, 1421 GL_REFERENCED_BY_FRAGMENT_SHADER, 1422 GL_REFERENCED_BY_VERTEX_SHADER, 1423 GL_LOCATION }; 1424 GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 1, -1 }; 1425 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 11, props2, 11, expected5, error); 1426 GLenum props3[] = { GL_NAME_LENGTH, 1427 GL_TYPE, 1428 GL_ARRAY_SIZE, 1429 GL_BLOCK_INDEX, 1430 GL_MATRIX_STRIDE, 1431 GL_IS_ROW_MAJOR, 1432 GL_ATOMIC_COUNTER_BUFFER_INDEX, 1433 GL_REFERENCED_BY_COMPUTE_SHADER, 1434 GL_REFERENCED_BY_FRAGMENT_SHADER, 1435 GL_REFERENCED_BY_VERTEX_SHADER, 1436 GL_LOCATION }; 1437 GLint expected6[] = { 27, 5126, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, -1 }; 1438 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 11, props3, 11, expected6, 1439 error); 1440 1441 GLenum prop = GL_ACTIVE_VARIABLES; 1442 const GLsizei bufSize = 1000; 1443 GLsizei length; 1444 GLint param[bufSize]; 1445 std::set<GLuint> exp; 1446 exp.insert(indicesU["a"]); 1447 exp.insert(indicesU["b"]); 1448 exp.insert(indicesU["c"]); 1449 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param); 1450 for (int i = 0; i < length; ++i) 1451 { 1452 if (exp.find(param[i]) == exp.end()) 1453 { 1454 m_context.getTestContext().getLog() 1455 << tcu::TestLog::Message 1456 << "Unexpected index found in active variables of SimpleBlock: " << param[i] 1457 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK" 1458 << tcu::TestLog::EndMessage; 1459 glDeleteProgram(program); 1460 return ERROR; 1461 } 1462 else if (length != 3) 1463 { 1464 m_context.getTestContext().getLog() 1465 << tcu::TestLog::Message 1466 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK" 1467 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage; 1468 glDeleteProgram(program); 1469 return ERROR; 1470 } 1471 } 1472 std::set<GLuint> exp2; 1473 exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]); 1474 exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]); 1475 exp2.insert(indicesU["NotSoSimpleBlockk.c"]); 1476 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length, 1477 param); 1478 for (int i = 0; i < length; ++i) 1479 { 1480 if (exp2.find(param[i]) == exp2.end()) 1481 { 1482 m_context.getTestContext().getLog() 1483 << tcu::TestLog::Message 1484 << "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i] 1485 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK" 1486 << tcu::TestLog::EndMessage; 1487 glDeleteProgram(program); 1488 return ERROR; 1489 } 1490 else if (length != 3) 1491 { 1492 m_context.getTestContext().getLog() 1493 << tcu::TestLog::Message 1494 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK" 1495 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage; 1496 glDeleteProgram(program); 1497 return ERROR; 1498 } 1499 } 1500 1501 GLint res; 1502 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res); 1503 if (res < 3) 1504 { 1505 m_context.getTestContext().getLog() 1506 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!" 1507 << tcu::TestLog::EndMessage; 1508 glDeleteProgram(program); 1509 return ERROR; 1510 } 1511 1512 glDeleteProgram(program); 1513 return error; 1514 } 1515}; 1516 1517class TransformFeedbackTypes : public SimpleShaders 1518{ 1519 virtual std::string Title() 1520 { 1521 return "Transform Feedback Varying Types"; 1522 } 1523 1524 virtual std::string ShadersDesc() 1525 { 1526 return "fallthrough fragment and vertex shaders with different types of out variables used"; 1527 } 1528 1529 virtual std::string PurposeExt() 1530 { 1531 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n"; 1532 } 1533 1534 virtual std::string VertexShader() 1535 { 1536 return "#version 310 es \n" 1537 "in vec4 position; \n" 1538 "" 1539 "flat out highp vec4 a; \n" 1540 "out mediump float b[2]; \n" 1541 "flat out highp uvec2 c; \n" 1542 "flat out highp uint d; \n" 1543 "out mediump vec3 e[2]; \n" 1544 "flat out int f; \n" 1545 "" 1546 "void main(void) \n" 1547 "{ \n" 1548 " vec4 pos; \n" 1549 " a = vec4(1); \n" 1550 " b[0] = 1.1; \n" 1551 " b[1] = 1.1; \n" 1552 " c = uvec2(1u); \n" 1553 " d = 1u; \n" 1554 " e[0] = vec3(1.1); \n" 1555 " e[1] = vec3(1.1); \n" 1556 " f = 1; \n" 1557 " gl_Position = position; \n" 1558 "}"; 1559 } 1560 1561 virtual long Run() 1562 { 1563 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 1564 glBindAttribLocation(program, 0, "position"); 1565 const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" }; 1566 glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS); 1567 LinkProgram(program); 1568 1569 long error = NO_ERROR; 1570 1571 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error); 1572 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error); 1573 1574 std::map<std::string, GLuint> indices; 1575 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error); 1576 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error); 1577 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error); 1578 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error); 1579 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error); 1580 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error); 1581 1582 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error); 1583 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error); 1584 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error); 1585 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error); 1586 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error); 1587 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error); 1588 1589 GLenum props[] = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE }; 1590 GLint expected[] = { 2, 35666, 1 }; 1591 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error); 1592 GLint expected2[] = { 5, 5126, 1 }; 1593 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2, 1594 error); 1595 GLint expected3[] = { 5, 5126, 1 }; 1596 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3, 1597 error); 1598 GLint expected4[] = { 2, 36294, 1 }; 1599 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error); 1600 GLint expected5[] = { 2, 5125, 1 }; 1601 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error); 1602 GLint expected6[] = { 2, 35665, 2 }; 1603 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error); 1604 1605 glDeleteProgram(program); 1606 return error; 1607 } 1608}; 1609 1610class AtomicCounterSimple : public ComputeShaderTest 1611{ 1612public: 1613 virtual std::string Title() 1614 { 1615 return "Atomic Counter Buffer Simple Test"; 1616 } 1617 1618 virtual std::string ShadersDesc() 1619 { 1620 return "compute shader with atomic counters used"; 1621 } 1622 1623 virtual std::string PurposeExt() 1624 { 1625 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n"; 1626 } 1627 1628 virtual long Run() 1629 { 1630 1631 GLint max_buffer_bindings = 0; 1632 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings); 1633 if (max_buffer_bindings < 6) 1634 { 1635 OutputNotSupported("Test requires at least 6 atomic counter buffer binding points."); 1636 return NOT_SUPPORTED; 1637 } 1638 1639 const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in; \n" 1640 "layout(std430) buffer Output { \n" 1641 " mediump vec4 data; \n" 1642 "} g_out; \n" 1643 "" 1644 "layout (binding = 1, offset = 0) uniform highp atomic_uint a; \n" 1645 "layout (binding = 2, offset = 0) uniform highp atomic_uint b; \n" 1646 "layout (binding = 2, offset = 4) uniform highp atomic_uint c; \n" 1647 "layout (binding = 5, offset = 0) uniform highp atomic_uint d[3]; \n" 1648 "layout (binding = 5, offset = 12) uniform highp atomic_uint e; \n" 1649 "" 1650 "void main() { \n" 1651 " uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n" 1652 " uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n" 1653 " uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n" 1654 " uint w = atomicCounterIncrement(e); \n" 1655 " g_out.data = vec4(float(x), float(y), float(z), float(w)); \n" 1656 "}"; 1657 1658 GLuint program = CreateComputeProgram(glsl_cs); 1659 glLinkProgram(program); 1660 if (!CheckProgram(program)) 1661 { 1662 glDeleteProgram(program); 1663 return ERROR; 1664 } 1665 glUseProgram(program); 1666 1667 long error = NO_ERROR; 1668 1669 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error); 1670 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error); 1671 1672 std::map<std::string, GLuint> indicesU; 1673 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error); 1674 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error); 1675 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error); 1676 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error); 1677 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error); 1678 1679 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error); 1680 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error); 1681 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error); 1682 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error); 1683 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error); 1684 1685 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error); 1686 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error); 1687 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error); 1688 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error); 1689 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error); 1690 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error); 1691 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error); 1692 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error); 1693 1694 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX; 1695 const GLsizei bufSize = 1000; 1696 GLsizei length; 1697 GLint res; 1698 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res); 1699 1700 GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES }; 1701 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res); 1702 GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) }; 1703 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error); 1704 1705 GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES }; 1706 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res); 1707 GLint expected2[] = { 2, 8, 2 }; 1708 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error); 1709 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res); 1710 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error); 1711 1712 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res); 1713 GLint expected3[] = { 5, 16, 2 }; 1714 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error); 1715 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res); 1716 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error); 1717 1718 GLenum prop2 = GL_ACTIVE_VARIABLES; 1719 GLint param[bufSize]; 1720 std::set<GLuint> exp; 1721 exp.insert(indicesU["b"]); 1722 exp.insert(indicesU["c"]); 1723 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res); 1724 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param); 1725 for (int i = 0; i < length; ++i) 1726 { 1727 if (exp.find(param[i]) == exp.end() || length != 2) 1728 { 1729 m_context.getTestContext().getLog() 1730 << tcu::TestLog::Message << "Length: " << length 1731 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i] 1732 << tcu::TestLog::EndMessage; 1733 glDeleteProgram(program); 1734 return ERROR; 1735 } 1736 } 1737 std::set<GLuint> exp2; 1738 GLint param2[bufSize]; 1739 exp2.insert(indicesU["d"]); 1740 exp2.insert(indicesU["e"]); 1741 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res); 1742 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2); 1743 for (int i = 0; i < length; ++i) 1744 { 1745 if (exp2.find(param2[i]) == exp2.end() || length != 2) 1746 { 1747 m_context.getTestContext().getLog() 1748 << tcu::TestLog::Message << "Length: " << length 1749 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i] 1750 << tcu::TestLog::EndMessage; 1751 glDeleteProgram(program); 1752 return ERROR; 1753 } 1754 } 1755 1756 glDeleteProgram(program); 1757 return error; 1758 } 1759}; 1760 1761class AtomicCounterSimpleOneBuffer : public ComputeShaderTest 1762{ 1763public: 1764 virtual std::string Title() 1765 { 1766 return "Atomic Counter Buffer Simple One Buffer Test"; 1767 } 1768 1769 virtual std::string ShadersDesc() 1770 { 1771 return "compute shader with atomic counters used"; 1772 } 1773 1774 virtual std::string PurposeExt() 1775 { 1776 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n"; 1777 } 1778 1779 virtual long Run() 1780 { 1781 1782 GLint max_buffer_bindings = 0; 1783 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings); 1784 if (max_buffer_bindings < 3) 1785 { 1786 OutputNotSupported("Test requires at least 3 atomic counter buffer binding points."); 1787 return NOT_SUPPORTED; 1788 } 1789 1790 const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in; \n" 1791 "layout(std430) buffer Output { \n" 1792 " mediump vec4 data; \n" 1793 "} g_out; \n" 1794 "" 1795 "layout (binding = 0, offset = 0) uniform highp atomic_uint a; \n" 1796 "layout (binding = 0, offset = 4) uniform highp atomic_uint b[3]; \n" 1797 "layout (binding = 0, offset = 16) uniform highp atomic_uint c; \n" 1798 "" 1799 "void main() { \n" 1800 " uint x = atomicCounterIncrement(b[0]) + atomicCounterIncrement(a); \n" 1801 " uint y = atomicCounterIncrement(b[1]) + atomicCounterIncrement(a); \n" 1802 " uint z = atomicCounterIncrement(b[2]) + atomicCounterIncrement(a); \n" 1803 " uint w = atomicCounterIncrement(c); \n" 1804 " g_out.data = vec4(float(x), float(y), float(z), float(w)); \n" 1805 "}"; 1806 1807 GLuint program = CreateComputeProgram(glsl_cs); 1808 glLinkProgram(program); 1809 if (!CheckProgram(program)) 1810 { 1811 glDeleteProgram(program); 1812 return ERROR; 1813 } 1814 glUseProgram(program); 1815 1816 long error = NO_ERROR; 1817 1818 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 1, error); 1819 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 3, error); 1820 1821 std::map<std::string, GLuint> indicesU; 1822 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error); 1823 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error); 1824 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error); 1825 1826 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error); 1827 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b[0]", error); 1828 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error); 1829 1830 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error); 1831 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error); 1832 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error); 1833 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[0]", -1, error); 1834 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[1]", -1, error); 1835 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[2]", -1, error); 1836 1837 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX; 1838 const GLsizei bufSize = 1000; 1839 GLsizei length; 1840 GLint res; 1841 1842 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res); 1843 if (res != 0) 1844 { 1845 m_context.getTestContext().getLog() 1846 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage; 1847 glDeleteProgram(program); 1848 return ERROR; 1849 } 1850 1851 GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES }; 1852 GLint expected[] = { 0, 20, 3 }; 1853 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props, 3, expected, error); 1854 1855 GLenum prop2 = GL_ACTIVE_VARIABLES; 1856 GLint param[bufSize]; 1857 std::set<GLuint> exp; 1858 exp.insert(indicesU["a"]); 1859 exp.insert(indicesU["b"]); 1860 exp.insert(indicesU["c"]); 1861 1862 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res); 1863 if (res != 0) 1864 { 1865 m_context.getTestContext().getLog() 1866 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage; 1867 glDeleteProgram(program); 1868 return ERROR; 1869 } 1870 1871 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param); 1872 for (int i = 0; i < length; ++i) 1873 { 1874 if (exp.find(param[i]) == exp.end() || length != 3) 1875 { 1876 m_context.getTestContext().getLog() 1877 << tcu::TestLog::Message << "Length: " << length 1878 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i] 1879 << tcu::TestLog::EndMessage; 1880 glDeleteProgram(program); 1881 return ERROR; 1882 } 1883 } 1884 1885 glDeleteProgram(program); 1886 return error; 1887 } 1888}; 1889 1890class InvalidValueTest : public SimpleShaders 1891{ 1892 virtual std::string Title() 1893 { 1894 return "Invalid Value Test"; 1895 } 1896 1897 virtual std::string PassCriteria() 1898 { 1899 return "GL_INVALID_VALUE error is generated after every function call."; 1900 } 1901 1902 virtual std::string Purpose() 1903 { 1904 return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec."; 1905 } 1906 1907 virtual std::string Method() 1908 { 1909 return "Call functions with invalid values and check if GL_INVALID_VALUE was generated."; 1910 } 1911 1912 virtual long Run() 1913 { 1914 long error = NO_ERROR; 1915 1916 GLint res; 1917 GLsizei len = 0; 1918 GLchar name[100] = { '\0' }; 1919 GLenum props[1] = { GL_NAME_LENGTH }; 1920 1921 m_context.getTestContext().getLog() 1922 << tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object" 1923 << tcu::TestLog::EndMessage; 1924 glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res); 1925 ExpectError(GL_INVALID_VALUE, error); 1926 glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie"); 1927 ExpectError(GL_INVALID_VALUE, error); 1928 glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name); 1929 ExpectError(GL_INVALID_VALUE, error); 1930 glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res); 1931 ExpectError(GL_INVALID_VALUE, error); 1932 glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie"); 1933 ExpectError(GL_INVALID_VALUE, error); 1934 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage; 1935 1936 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 1937 glBindAttribLocation(program, 0, "position"); 1938 LinkProgram(program); 1939 1940 m_context.getTestContext().getLog() 1941 << tcu::TestLog::Message 1942 << "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName" 1943 << tcu::TestLog::EndMessage; 1944 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage; 1945 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name); 1946 ExpectError(GL_INVALID_VALUE, error); 1947 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2: finished" << tcu::TestLog::EndMessage; 1948 1949 m_context.getTestContext().getLog() 1950 << tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv" 1951 << tcu::TestLog::EndMessage; 1952 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res); 1953 ExpectError(GL_INVALID_VALUE, error); 1954 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3: finished" << tcu::TestLog::EndMessage; 1955 1956 std::string str = "position"; 1957 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str())); 1958 ExpectError(GL_INVALID_VALUE, error); 1959 GLenum prop = GL_NAME_LENGTH; 1960 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res); 1961 ExpectError(GL_INVALID_VALUE, error); 1962 1963 glDeleteProgram(program); 1964 return error; 1965 } 1966}; 1967 1968class InvalidEnumTest : public SimpleShaders 1969{ 1970 virtual std::string Title() 1971 { 1972 return "Invalid Enum Test"; 1973 } 1974 1975 virtual std::string PassCriteria() 1976 { 1977 return "GL_INVALID_ENUM error is generated after every function call."; 1978 } 1979 1980 virtual std::string Purpose() 1981 { 1982 return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec."; 1983 } 1984 1985 virtual std::string Method() 1986 { 1987 return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated."; 1988 } 1989 1990 // make sure at least one atomic counter resource is active 1991 virtual std::string FragmentShader() 1992 { 1993 return "#version 310 es \n" 1994 "layout (binding = 0, offset = 0) uniform highp atomic_uint a;\n" 1995 "out mediump vec4 outColor; \n" 1996 "void main(void) { \n" 1997 " uint b = atomicCounterIncrement(a); \n" 1998 " outColor = vec4(float(b)); \n" 1999 "} \n"; 2000 } 2001 2002 virtual long Run() 2003 { 2004 GLint max_buffers = 0, max_counters = 0; 2005 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_buffers); 2006 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &max_counters); 2007 if (max_buffers < 1 || max_counters < 1) 2008 { 2009 OutputNotSupported("Test requires at least 1 atomic counter."); 2010 return NOT_SUPPORTED; 2011 } 2012 2013 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 2014 glBindAttribLocation(program, 0, "position"); 2015 LinkProgram(program); 2016 2017 long error = NO_ERROR; 2018 2019 GLint res; 2020 GLsizei len = 0; 2021 GLchar name[100] = { '\0' }; 2022 GLenum props[1] = { GL_TEXTURE_1D }; 2023 2024 m_context.getTestContext().getLog() 2025 << tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER in " 2026 "GetProgramResourceIndex or GetProgramResourceName" 2027 << tcu::TestLog::EndMessage; 2028 glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name); 2029 ExpectError(GL_INVALID_ENUM, error); 2030 glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name); 2031 ExpectError(GL_INVALID_ENUM, error); 2032 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage; 2033 2034 m_context.getTestContext().getLog() 2035 << tcu::TestLog::Message 2036 << "Case 2: <props> is not a property name supported by the command GetProgramResourceiv" 2037 << tcu::TestLog::EndMessage; 2038 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res); 2039 ExpectError(GL_INVALID_ENUM, error); 2040 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage; 2041 2042 glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position"); 2043 ExpectError(GL_INVALID_ENUM, error); 2044 2045 glDeleteProgram(program); 2046 return error; 2047 } 2048}; 2049 2050class InvalidOperationTest : public SimpleShaders 2051{ 2052 virtual std::string Title() 2053 { 2054 return "Invalid Operation Test"; 2055 } 2056 2057 virtual std::string PassCriteria() 2058 { 2059 return "GL_INVALID_OPERATION error is generated after every function call."; 2060 } 2061 2062 virtual std::string Purpose() 2063 { 2064 return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec."; 2065 } 2066 2067 virtual std::string Method() 2068 { 2069 return "Perform invalid operation and check if GL_INVALID_OPERATION was generated."; 2070 } 2071 2072 virtual long Run() 2073 { 2074 long error = NO_ERROR; 2075 2076 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 2077 GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 2078 glBindAttribLocation(program, 0, "position"); 2079 LinkProgram(program); 2080 2081 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER); 2082 GLint res; 2083 GLsizei len = 0; 2084 GLchar name[100] = { '\0' }; 2085 GLenum props[1] = { GL_OFFSET }; 2086 2087 m_context.getTestContext().getLog() 2088 << tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage; 2089 glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res); 2090 ExpectError(GL_INVALID_OPERATION, error); 2091 glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie"); 2092 ExpectError(GL_INVALID_OPERATION, error); 2093 glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name); 2094 ExpectError(GL_INVALID_OPERATION, error); 2095 glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res); 2096 ExpectError(GL_INVALID_OPERATION, error); 2097 glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie"); 2098 ExpectError(GL_INVALID_OPERATION, error); 2099 glDeleteShader(sh); 2100 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage; 2101 2102 m_context.getTestContext().getLog() 2103 << tcu::TestLog::Message << "Case 2: <pname> is not supported in GetProgramInterfaceiv" 2104 << tcu::TestLog::EndMessage; 2105 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res); 2106 ExpectError(GL_INVALID_OPERATION, error); 2107 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage; 2108 2109 m_context.getTestContext().getLog() 2110 << tcu::TestLog::Message << "Case 3: <props> is not supported in GetProgramResourceiv" 2111 << tcu::TestLog::EndMessage; 2112 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res); 2113 ExpectError(GL_INVALID_OPERATION, error); 2114 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage; 2115 2116 m_context.getTestContext().getLog() 2117 << tcu::TestLog::Message << "Case 4: <program> has not been linked in GetProgramResourceLocation" 2118 << tcu::TestLog::EndMessage; 2119 glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie"); 2120 ExpectError(GL_INVALID_OPERATION, error); 2121 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished" << tcu::TestLog::EndMessage; 2122 2123 glDeleteProgram(program); 2124 glDeleteProgram(program2); 2125 return error; 2126 } 2127}; 2128 2129class ShaderStorageBlock : public ComputeShaderTest 2130{ 2131 virtual std::string Title() 2132 { 2133 return "Shader Storage Block Test"; 2134 } 2135 2136 virtual std::string ShadersDesc() 2137 { 2138 return "compute shader different types of storage blocks used"; 2139 } 2140 2141 virtual std::string PurposeExt() 2142 { 2143 return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface " 2144 "params.\n"; 2145 } 2146 2147 virtual std::string ComputeShader() 2148 { 2149 return "layout(local_size_x = 1, local_size_y = 1) in; \n" 2150 "layout(std430) buffer Output { \n" 2151 " mediump vec4 data; \n" 2152 "} g_out; \n" 2153 "" 2154 "struct U { \n" 2155 " bool a[3]; \n" 2156 " mediump vec4 b; \n" 2157 " mediump mat3 c; \n" 2158 " mediump float d[2]; \n" 2159 "}; \n" 2160 "struct UU { \n" 2161 " U a; \n" 2162 " U b[2]; \n" 2163 " uvec2 c; \n" 2164 "}; \n" 2165 "" 2166 "layout(binding=4) buffer TrickyBuffer { \n" 2167 " UU a[3]; \n" 2168 " mediump mat4 b; \n" 2169 " uint c; \n" 2170 "} e[2]; \n" 2171 "" 2172 "layout(binding = 0) buffer SimpleBuffer { \n" 2173 " mediump mat3x2 a; \n" 2174 " mediump mat4 b; \n" 2175 " mediump vec4 c; \n" 2176 "}; \n" 2177 "" 2178 "layout(binding = 1) buffer NotSoSimpleBuffer { \n" 2179 " ivec2 a[4]; \n" 2180 " mediump mat3 b[2]; \n" 2181 " mediump mat2 c; \n" 2182 "} d; \n" 2183 "" 2184 "void main() { \n" 2185 " mediump float tmp; \n" 2186 " mediump float tmp2; \n" 2187 " tmp = e[0].a[0].b[0].d[0] * float(e[1].c); \n" 2188 " tmp2 = a[0][0] * b[0][0] * c.x; \n" 2189 " tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0]; \n" 2190 " g_out.data = vec4(0, 1, 0, 1) * tmp * tmp2; \n" 2191 "}"; 2192 } 2193 2194 virtual long Run() 2195 { 2196 GLuint program = CreateComputeProgram(ComputeShader()); 2197 glLinkProgram(program); 2198 if (!CheckProgram(program)) 2199 { 2200 glDeleteProgram(program); 2201 return ERROR; 2202 } 2203 glUseProgram(program); 2204 2205 long error = NO_ERROR; 2206 2207 GLint res; 2208 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error); 2209 glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res); 2210 if (res < 7) 2211 { 2212 m_context.getTestContext().getLog() 2213 << tcu::TestLog::Message 2214 << "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n" 2215 << "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage; 2216 glDeleteProgram(program); 2217 return ERROR; 2218 } 2219 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 5, error); 2220 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error); 2221 2222 std::map<std::string, GLuint> indicesSSB; 2223 std::map<std::string, GLuint> indicesBV; 2224 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error); 2225 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error); 2226 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error); 2227 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error); 2228 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error); 2229 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error); 2230 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error); 2231 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error); 2232 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error); 2233 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error); 2234 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error); 2235 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error); 2236 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error); 2237 2238 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer", 2239 error); 2240 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 2241 "NotSoSimpleBuffer", error); 2242 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]", 2243 error); 2244 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]", 2245 error); 2246 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error); 2247 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error); 2248 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error); 2249 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"], 2250 "NotSoSimpleBuffer.a[0]", error); 2251 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"], 2252 "NotSoSimpleBuffer.c", error); 2253 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"], 2254 "NotSoSimpleBuffer.b[0]", error); 2255 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 2256 "TrickyBuffer.a[0].b[0].d[0]", error); 2257 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error); 2258 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error); 2259 2260 GLenum props[] = { GL_NAME_LENGTH, 2261 GL_BUFFER_BINDING, 2262 GL_NUM_ACTIVE_VARIABLES, 2263 GL_REFERENCED_BY_COMPUTE_SHADER, 2264 GL_REFERENCED_BY_FRAGMENT_SHADER, 2265 GL_REFERENCED_BY_VERTEX_SHADER }; 2266 GLint expected[] = { 13, 0, 3, 1, 0, 0 }; 2267 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 6, props, 6, expected, 2268 error); 2269 GLenum props2[] = { GL_NAME_LENGTH, GL_BUFFER_BINDING, GL_REFERENCED_BY_COMPUTE_SHADER, 2270 GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_VERTEX_SHADER }; 2271 GLint expected2[] = { 18, 1, 1, 0, 0 }; 2272 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 5, props2, 5, 2273 expected2, error); 2274 GLint expected3[] = { 16, 4, 1, 0, 0 }; 2275 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 5, props2, 5, 2276 expected3, error); 2277 GLint expected4[] = { 16, 5, 1, 0, 0 }; 2278 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 5, props2, 5, 2279 expected4, error); 2280 2281 GLenum props3[] = { GL_NAME_LENGTH, 2282 GL_TYPE, 2283 GL_ARRAY_SIZE, 2284 GL_BLOCK_INDEX, 2285 GL_ARRAY_STRIDE, 2286 GL_IS_ROW_MAJOR, 2287 GL_REFERENCED_BY_COMPUTE_SHADER, 2288 GL_REFERENCED_BY_FRAGMENT_SHADER, 2289 GL_REFERENCED_BY_VERTEX_SHADER, 2290 GL_TOP_LEVEL_ARRAY_SIZE, 2291 GL_TOP_LEVEL_ARRAY_STRIDE }; 2292 GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 1, 0, 0, 1, 0 }; 2293 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props3, 11, expected5, error); 2294 GLenum props4[] = { GL_NAME_LENGTH, 2295 GL_TYPE, 2296 GL_ARRAY_SIZE, 2297 GL_BLOCK_INDEX, 2298 GL_MATRIX_STRIDE, 2299 GL_IS_ROW_MAJOR, 2300 GL_REFERENCED_BY_COMPUTE_SHADER, 2301 GL_REFERENCED_BY_FRAGMENT_SHADER, 2302 GL_REFERENCED_BY_VERTEX_SHADER, 2303 GL_TOP_LEVEL_ARRAY_SIZE }; 2304 GLint expected6[] = { 28, 5126, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 1, 0, 0, 3 }; 2305 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 10, props4, 10, 2306 expected6, error); 2307 2308 GLenum prop = GL_ACTIVE_VARIABLES; 2309 const GLsizei bufSize = 1000; 2310 GLsizei length; 2311 GLint param[bufSize]; 2312 std::set<GLuint> exp; 2313 exp.insert(indicesBV["a"]); 2314 exp.insert(indicesBV["b"]); 2315 exp.insert(indicesBV["c"]); 2316 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length, 2317 param); 2318 for (int i = 0; i < length; ++i) 2319 { 2320 if (exp.find(param[i]) == exp.end()) 2321 { 2322 m_context.getTestContext().getLog() 2323 << tcu::TestLog::Message 2324 << "Unexpected index found in active variables of SimpleBuffer: " << param[i] 2325 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: " 2326 "GL_SHADER_STORAGE_BLOCK" 2327 << tcu::TestLog::EndMessage; 2328 glDeleteProgram(program); 2329 return ERROR; 2330 } 2331 else if (length != 3) 2332 { 2333 m_context.getTestContext().getLog() 2334 << tcu::TestLog::Message 2335 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK" 2336 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage; 2337 glDeleteProgram(program); 2338 return ERROR; 2339 } 2340 } 2341 std::set<GLuint> exp2; 2342 exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]); 2343 exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]); 2344 exp2.insert(indicesBV["NotSoSimpleBuffer.c"]); 2345 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize, 2346 &length, param); 2347 for (int i = 0; i < length; ++i) 2348 { 2349 if (exp2.find(param[i]) == exp2.end()) 2350 { 2351 m_context.getTestContext().getLog() 2352 << tcu::TestLog::Message 2353 << "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i] 2354 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: " 2355 "GL_SHADER_STORAGE_BLOCK" 2356 << tcu::TestLog::EndMessage; 2357 glDeleteProgram(program); 2358 return ERROR; 2359 } 2360 else if (length != 3) 2361 { 2362 m_context.getTestContext().getLog() 2363 << tcu::TestLog::Message 2364 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK" 2365 << param[i] << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage; 2366 glDeleteProgram(program); 2367 return ERROR; 2368 } 2369 } 2370 2371 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res); 2372 if (res < 3) 2373 { 2374 m_context.getTestContext().getLog() 2375 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n" 2376 << "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage; 2377 return ERROR; 2378 } 2379 2380 glDeleteProgram(program); 2381 return error; 2382 } 2383}; 2384 2385class NullLength : public SimpleShaders 2386{ 2387 2388 virtual std::string Title() 2389 { 2390 return "NULL Length Test"; 2391 } 2392 2393 virtual std::string PurposeExt() 2394 { 2395 return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't " 2396 "crash).\n"; 2397 } 2398 2399 virtual std::string VertexShader() 2400 { 2401 return "#version 310 es \n" 2402 "in vec4 position; \n" 2403 "void main(void) \n" 2404 "{ \n" 2405 " gl_Position = position; \n" 2406 "}"; 2407 } 2408 2409 virtual std::string FragmentShader() 2410 { 2411 return "#version 310 es \n" 2412 "out mediump vec4 color; \n" 2413 "void main() { \n" 2414 " color = vec4(0, 1, 0, 1); \n" 2415 "}"; 2416 } 2417 2418 virtual long Run() 2419 { 2420 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 2421 glBindAttribLocation(program, 0, "position"); 2422 LinkProgram(program); 2423 2424 GLchar name[1024] = { '\0' }; 2425 GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color"); 2426 GLenum prop = GL_ARRAY_SIZE; 2427 GLint res; 2428 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name); 2429 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res); 2430 2431 std::string expected = "color"; 2432 if (name != expected) 2433 { 2434 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected 2435 << ", got: " << name << tcu::TestLog::EndMessage; 2436 glDeleteProgram(program); 2437 return ERROR; 2438 } 2439 else if (res != 1) 2440 { 2441 m_context.getTestContext().getLog() 2442 << tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage; 2443 glDeleteProgram(program); 2444 return ERROR; 2445 } 2446 2447 glDeleteProgram(program); 2448 return NO_ERROR; 2449 } 2450}; 2451 2452class ArraysOfArrays : public SimpleShaders 2453{ 2454 2455 virtual std::string Title() 2456 { 2457 return "Arrays Of Arrays Test"; 2458 } 2459 2460 virtual std::string ShadersDesc() 2461 { 2462 return "fallthrough fragment and vertex shaders with multi dimensional uniform array used"; 2463 } 2464 2465 virtual std::string PurposeExt() 2466 { 2467 return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays feature.\n"; 2468 } 2469 2470 virtual std::string VertexShader() 2471 { 2472 return "#version 310 es \n" 2473 "in vec4 position; \n" 2474 "uniform mediump vec4 a[3][4][5]; \n" 2475 "void main(void) \n" 2476 "{ \n" 2477 " gl_Position = position + a[2][1][0]; \n" 2478 "}"; 2479 } 2480 2481 virtual std::string FragmentShader() 2482 { 2483 return "#version 310 es \n" 2484 "out mediump vec4 color; \n" 2485 "void main() { \n" 2486 " color = vec4(0, 1, 0, 1); \n" 2487 "}"; 2488 } 2489 2490 virtual long Run() 2491 { 2492 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 2493 glBindAttribLocation(program, 0, "position"); 2494 LinkProgram(program); 2495 2496 long error = NO_ERROR; 2497 2498 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error); 2499 2500 std::map<std::string, GLuint> indices; 2501 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error); 2502 VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error); 2503 2504 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error); 2505 2506 GLenum props[] = { GL_NAME_LENGTH, 2507 GL_TYPE, 2508 GL_ARRAY_SIZE, 2509 GL_OFFSET, 2510 GL_BLOCK_INDEX, 2511 GL_ARRAY_STRIDE, 2512 GL_MATRIX_STRIDE, 2513 GL_IS_ROW_MAJOR, 2514 GL_ATOMIC_COUNTER_BUFFER_INDEX, 2515 GL_REFERENCED_BY_COMPUTE_SHADER, 2516 GL_REFERENCED_BY_FRAGMENT_SHADER, 2517 GL_REFERENCED_BY_VERTEX_SHADER, 2518 GL_LOCATION }; 2519 GLint expected[] = { 11, 35666, 5, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a[2][1]") }; 2520 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 13, props, 13, expected, error); 2521 2522 glDeleteProgram(program); 2523 return error; 2524 } 2525}; 2526 2527class TopLevelArray : public ComputeShaderTest 2528{ 2529 2530 virtual std::string Title() 2531 { 2532 return "Top Level Array Test"; 2533 } 2534 2535 virtual std::string ShadersDesc() 2536 { 2537 return "compute shader with multi dimensional array used inside storage block"; 2538 } 2539 2540 virtual std::string PurposeExt() 2541 { 2542 return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n" 2543 " and GL_TOP_LEVEL_ARRAY_STRIDE.\n"; 2544 } 2545 2546 virtual std::string ComputeShader() 2547 { 2548 return "layout(local_size_x = 1, local_size_y = 1) in; \n" 2549 "layout(std430) buffer Outp { \n" 2550 " mediump vec4 d; \n" 2551 "} g_out; \n" 2552 "" 2553 "buffer Block { \n" 2554 " mediump vec4 a[5][4][3]; \n" 2555 "}; \n" 2556 "" 2557 "void main(void) \n" 2558 "{ \n" 2559 " g_out.d = a[0][0][0]; \n" 2560 "}"; 2561 } 2562 2563 virtual long Run() 2564 { 2565 GLuint program = CreateComputeProgram(ComputeShader()); 2566 glLinkProgram(program); 2567 if (!CheckProgram(program)) 2568 { 2569 glDeleteProgram(program); 2570 return ERROR; 2571 } 2572 glUseProgram(program); 2573 2574 long error = NO_ERROR; 2575 2576 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error); 2577 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error); 2578 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 2, error); 2579 2580 std::map<std::string, GLuint> indicesSSB; 2581 std::map<std::string, GLuint> indicesBV; 2582 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error); 2583 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error); 2584 2585 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error); 2586 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error); 2587 2588 GLenum props3[] = { GL_NAME_LENGTH, 2589 GL_TYPE, 2590 GL_ARRAY_SIZE, 2591 GL_BLOCK_INDEX, 2592 GL_IS_ROW_MAJOR, 2593 GL_REFERENCED_BY_COMPUTE_SHADER, 2594 GL_REFERENCED_BY_FRAGMENT_SHADER, 2595 GL_REFERENCED_BY_VERTEX_SHADER, 2596 GL_TOP_LEVEL_ARRAY_SIZE }; 2597 GLint expected5[] = { 11, 35666, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 1, 0, 0, 5 }; 2598 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 9, props3, 9, expected5, error); 2599 2600 GLenum prop = GL_TOP_LEVEL_ARRAY_STRIDE; 2601 GLsizei len; 2602 GLint res; 2603 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res); 2604 if (res <= 0) 2605 { 2606 m_context.getTestContext().getLog() 2607 << tcu::TestLog::Message 2608 << "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n" 2609 << "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage; 2610 glDeleteProgram(program); 2611 return ERROR; 2612 } 2613 2614 glDeleteProgram(program); 2615 return error; 2616 } 2617}; 2618 2619class SeparateProgramsVertex : public SimpleShaders 2620{ 2621public: 2622 virtual std::string Title() 2623 { 2624 return "Separate Program Vertex Shader Test"; 2625 } 2626 2627 virtual std::string ShadersDesc() 2628 { 2629 return "vertex shader as separate shader object"; 2630 } 2631 2632 virtual std::string PurposeExt() 2633 { 2634 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects " 2635 "functionality.\n"; 2636 } 2637 2638 virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings) 2639 { 2640 GLuint program = glCreateShaderProgramv(type, count, strings); 2641 GLint status = GL_TRUE; 2642 glGetProgramiv(program, GL_LINK_STATUS, &status); 2643 if (status == GL_FALSE) 2644 { 2645 GLsizei length; 2646 GLchar log[1024]; 2647 glGetProgramInfoLog(program, sizeof(log), &length, log); 2648 if (length > 1) 2649 { 2650 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n" 2651 << log << tcu::TestLog::EndMessage; 2652 } 2653 } 2654 return program; 2655 } 2656 2657 virtual long Run() 2658 { 2659 long error = NO_ERROR; 2660 2661 const char* srcVS = "#version 310 es \n" 2662 "layout(location = 0) in vec4 in_vertex; \n" 2663 "" 2664 "out mediump float r, g, b; \n" 2665 "out mediump vec4 iLikePie; \n" 2666 "" 2667 "uniform mediump float u; \n" 2668 "uniform mediump vec4 v; \n" 2669 "" 2670 "void main() { \n" 2671 " gl_Position = in_vertex; \n" 2672 " r = u; \n" 2673 " g = 0.0; \n" 2674 " b = 0.0; \n" 2675 " iLikePie = v; \n" 2676 "}"; 2677 2678 const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS); 2679 2680 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error); 2681 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error); 2682 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error); 2683 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error); 2684 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 12, error); 2685 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error); 2686 2687 std::map<std::string, GLuint> indicesU; 2688 std::map<std::string, GLuint> indicesI; 2689 std::map<std::string, GLuint> indicesO; 2690 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error); 2691 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error); 2692 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error); 2693 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "r", error); 2694 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "g", error); 2695 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "b", error); 2696 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "iLikePie", error); 2697 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error); 2698 2699 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error); 2700 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error); 2701 VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error); 2702 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["r"], "r", error); 2703 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["g"], "g", error); 2704 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error); 2705 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], "iLikePie", error); 2706 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error); 2707 2708 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error); 2709 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error); 2710 VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error); 2711 2712 GLenum props[] = { GL_NAME_LENGTH, 2713 GL_TYPE, 2714 GL_ARRAY_SIZE, 2715 GL_OFFSET, 2716 GL_BLOCK_INDEX, 2717 GL_ARRAY_STRIDE, 2718 GL_MATRIX_STRIDE, 2719 GL_IS_ROW_MAJOR, 2720 GL_ATOMIC_COUNTER_BUFFER_INDEX, 2721 GL_REFERENCED_BY_COMPUTE_SHADER, 2722 GL_REFERENCED_BY_FRAGMENT_SHADER, 2723 GL_REFERENCED_BY_VERTEX_SHADER, 2724 GL_LOCATION }; 2725 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(vs, "v") }; 2726 VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 13, props, 13, expected, error); 2727 2728 GLenum props2[] = { GL_NAME_LENGTH, 2729 GL_TYPE, 2730 GL_ARRAY_SIZE, 2731 GL_REFERENCED_BY_COMPUTE_SHADER, 2732 GL_REFERENCED_BY_FRAGMENT_SHADER, 2733 GL_REFERENCED_BY_VERTEX_SHADER, 2734 GL_LOCATION }; 2735 GLint expected2[] = { 10, 35666, 1, 0, 0, 1, 0 }; 2736 VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 7, props2, 7, expected2, error); 2737 2738 GLenum props3[] = { GL_NAME_LENGTH, 2739 GL_TYPE, 2740 GL_ARRAY_SIZE, 2741 GL_REFERENCED_BY_COMPUTE_SHADER, 2742 GL_REFERENCED_BY_FRAGMENT_SHADER, 2743 GL_REFERENCED_BY_VERTEX_SHADER }; 2744 GLint expected3[] = { 9, 35666, 1, 0, 0, 1 }; 2745 VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], 6, props3, 6, expected3, error); 2746 2747 glDeleteProgram(vs); 2748 return error; 2749 } 2750}; 2751 2752class SeparateProgramsFragment : public SeparateProgramsVertex 2753{ 2754 2755 virtual std::string Title() 2756 { 2757 return "Separate Program Fragment Shader Test"; 2758 } 2759 2760 virtual std::string ShadersDesc() 2761 { 2762 return "fragment shader as separate shader object"; 2763 } 2764 2765 virtual long Run() 2766 { 2767 long error = NO_ERROR; 2768 2769 const char* srcTCS = "#version 310 es \n" 2770 "out mediump vec4 fs_color; \n" 2771 "" 2772 "layout(location = 1) uniform mediump vec4 x; \n" 2773 "" 2774 "in mediump vec4 vs_color; \n" 2775 "void main() { \n" 2776 " fs_color = vs_color + x; \n" 2777 "}"; 2778 2779 const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS); 2780 2781 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error); 2782 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error); 2783 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error); 2784 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error); 2785 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error); 2786 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error); 2787 2788 std::map<std::string, GLuint> indicesI; 2789 std::map<std::string, GLuint> indicesO; 2790 std::map<std::string, GLuint> indicesU; 2791 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error); 2792 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error); 2793 VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error); 2794 2795 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error); 2796 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error); 2797 VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error); 2798 2799 VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error); 2800 2801 GLenum props2[] = { GL_NAME_LENGTH, 2802 GL_TYPE, 2803 GL_ARRAY_SIZE, 2804 GL_REFERENCED_BY_COMPUTE_SHADER, 2805 GL_REFERENCED_BY_FRAGMENT_SHADER, 2806 GL_REFERENCED_BY_VERTEX_SHADER }; 2807 GLint expected2[] = { 9, 35666, 1, 0, 1, 0 }; 2808 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 6, props2, 6, expected2, error); 2809 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 6, props2, 6, expected2, error); 2810 2811 GLenum props[] = { GL_NAME_LENGTH, 2812 GL_TYPE, 2813 GL_ARRAY_SIZE, 2814 GL_OFFSET, 2815 GL_BLOCK_INDEX, 2816 GL_ARRAY_STRIDE, 2817 GL_MATRIX_STRIDE, 2818 GL_IS_ROW_MAJOR, 2819 GL_ATOMIC_COUNTER_BUFFER_INDEX, 2820 GL_REFERENCED_BY_COMPUTE_SHADER, 2821 GL_REFERENCED_BY_FRAGMENT_SHADER, 2822 GL_REFERENCED_BY_VERTEX_SHADER, 2823 GL_LOCATION }; 2824 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 }; 2825 VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props, 13, expected, error); 2826 2827 glDeleteProgram(tcs); 2828 return error; 2829 } 2830}; 2831 2832class UniformBlockAdvanced : public SimpleShaders 2833{ 2834 virtual std::string Title() 2835 { 2836 return "Uniform Block Advanced Test"; 2837 } 2838 2839 virtual std::string ShadersDesc() 2840 { 2841 return "fallthrough fragment and vertex shaders with different types of uniform blocks used"; 2842 } 2843 2844 virtual std::string PurposeExt() 2845 { 2846 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n" 2847 "verify results of querying offset, strides and row order.\n"; 2848 } 2849 2850 virtual std::string VertexShader() 2851 { 2852 return "#version 310 es \n" 2853 "in vec4 position; \n" 2854 "" 2855 "layout(row_major) uniform SimpleBlock { \n" 2856 " mat4 a; \n" 2857 " vec4 b[10]; \n" 2858 "}; \n" 2859 "" 2860 "void main(void) \n" 2861 "{ \n" 2862 " float tmp; \n" 2863 " tmp = a[0][0] + b[0].x; \n" 2864 " gl_Position = position * tmp; \n" 2865 "}"; 2866 } 2867 2868 virtual long Run() 2869 { 2870 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 2871 glBindAttribLocation(program, 0, "position"); 2872 LinkProgram(program); 2873 2874 long error = NO_ERROR; 2875 2876 std::map<std::string, GLuint> indicesU; 2877 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error); 2878 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error); 2879 2880 GLenum props[] = { GL_IS_ROW_MAJOR }; 2881 GLint expected[] = { 1 }; 2882 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error); 2883 2884 GLenum prop = GL_MATRIX_STRIDE; 2885 GLsizei len; 2886 GLint res; 2887 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res); 2888 if (res < 1) 2889 { 2890 m_context.getTestContext().getLog() 2891 << tcu::TestLog::Message 2892 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n" 2893 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage; 2894 } 2895 prop = GL_OFFSET; 2896 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res); 2897 if (res < 0) 2898 { 2899 m_context.getTestContext().getLog() 2900 << tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n" 2901 << "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage; 2902 } 2903 prop = GL_ARRAY_STRIDE; 2904 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res); 2905 if (res < 1) 2906 { 2907 m_context.getTestContext().getLog() 2908 << tcu::TestLog::Message 2909 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n" 2910 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage; 2911 } 2912 2913 glDeleteProgram(program); 2914 return error; 2915 } 2916}; 2917 2918class ArrayNames : public SimpleShaders 2919{ 2920 2921 virtual std::string Title() 2922 { 2923 return "Array Names Test"; 2924 } 2925 2926 virtual std::string ShadersDesc() 2927 { 2928 return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used"; 2929 } 2930 2931 virtual std::string PurposeExt() 2932 { 2933 return "\n\n Purpose is to verify that GetProgramResourceLocation match " 2934 "name strings correctly.\n"; 2935 } 2936 2937 virtual std::string VertexShader() 2938 { 2939 return "#version 310 es \n" 2940 "in vec4 position; \n" 2941 "" 2942 "uniform mediump vec4 a[2]; \n" 2943 "" 2944 "void main(void) \n" 2945 "{ \n" 2946 " gl_Position = position + a[0] + a[1]; \n" 2947 "}"; 2948 } 2949 2950 virtual long Run() 2951 { 2952 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 2953 glBindAttribLocation(program, 0, "position"); 2954 LinkProgram(program); 2955 2956 long error = NO_ERROR; 2957 2958 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error); 2959 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error); 2960 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error); 2961 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error); 2962 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error); 2963 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error); 2964 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error); 2965 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error); 2966 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error); 2967 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error); 2968 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error); 2969 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error); 2970 2971 glDeleteProgram(program); 2972 return error; 2973 } 2974}; 2975 2976class BuffLength : public SimpleShaders 2977{ 2978 2979 virtual std::string Title() 2980 { 2981 return "Buff Length Test"; 2982 } 2983 2984 virtual std::string ShadersDesc() 2985 { 2986 return "fallthrough fragment shader and vertex with uniform of vec4 type used"; 2987 } 2988 2989 virtual std::string PurposeExt() 2990 { 2991 return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and " 2992 "GetProgramResourceiv is respected.\n"; 2993 } 2994 2995 virtual std::string VertexShader() 2996 { 2997 return "#version 310 es \n" 2998 "in vec4 position; \n" 2999 "" 3000 "uniform mediump vec4 someLongName; \n" 3001 "" 3002 "void main(void) \n" 3003 "{ \n" 3004 " gl_Position = position + someLongName; \n" 3005 "}"; 3006 } 3007 3008 virtual long Run() 3009 { 3010 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 3011 glBindAttribLocation(program, 0, "position"); 3012 LinkProgram(program); 3013 3014 long error = NO_ERROR; 3015 3016 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName"); 3017 GLsizei length; 3018 GLchar buff[3] = { 'a', 'b', 'c' }; 3019 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL); 3020 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff); 3021 if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c') 3022 { 3023 m_context.getTestContext().getLog() 3024 << tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage; 3025 error = ERROR; 3026 } 3027 glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff); 3028 if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c') 3029 { 3030 m_context.getTestContext().getLog() 3031 << tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage; 3032 error = ERROR; 3033 } 3034 if (length != 1) 3035 { 3036 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got " 3037 << length << tcu::TestLog::EndMessage; 3038 error = ERROR; 3039 } 3040 3041 GLint params[3] = { 1, 2, 3 }; 3042 GLenum props[] = { GL_NAME_LENGTH, 3043 GL_TYPE, 3044 GL_ARRAY_SIZE, 3045 GL_OFFSET, 3046 GL_BLOCK_INDEX, 3047 GL_ARRAY_STRIDE, 3048 GL_MATRIX_STRIDE, 3049 GL_IS_ROW_MAJOR, 3050 GL_ATOMIC_COUNTER_BUFFER_INDEX, 3051 GL_REFERENCED_BY_COMPUTE_SHADER, 3052 GL_REFERENCED_BY_FRAGMENT_SHADER, 3053 GL_REFERENCED_BY_VERTEX_SHADER, 3054 GL_LOCATION }; 3055 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL); 3056 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params); 3057 if (params[0] != 1 || params[1] != 2 || params[2] != 3) 3058 { 3059 m_context.getTestContext().getLog() 3060 << tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage; 3061 error = ERROR; 3062 } 3063 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params); 3064 if (params[0] != 13 || params[1] != 35666 || params[2] != 3) 3065 { 3066 m_context.getTestContext().getLog() 3067 << tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage; 3068 error = ERROR; 3069 } 3070 if (length != 2) 3071 { 3072 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got " 3073 << length << tcu::TestLog::EndMessage; 3074 error = ERROR; 3075 } 3076 3077 glDeleteProgram(program); 3078 return error; 3079 } 3080}; 3081 3082class NoLocations : public SimpleShaders 3083{ 3084 3085 virtual std::string Title() 3086 { 3087 return "No Locations Test"; 3088 } 3089 3090 virtual std::string ShadersDesc() 3091 { 3092 return "fragment and vertex shaders with no locations set"; 3093 } 3094 3095 virtual std::string VertexShader() 3096 { 3097 return "#version 310 es \n" 3098 "in vec4 a; \n" 3099 "in vec4 b; \n" 3100 "in vec4 c; \n" 3101 "in vec4 d; \n" 3102 "void main(void) \n" 3103 "{ \n" 3104 " gl_Position = a + b + c + d; \n" 3105 "}"; 3106 } 3107 3108 // fragment shader outputs need an explicit location per spec 3109 virtual std::string FragmentShader() 3110 { 3111 return "#version 310 es \n" 3112 "layout (location=0) out mediump vec4 a; \n" 3113 "layout (location=1) out mediump vec4 b; \n" 3114 "layout (location=2) out mediump vec4 c; \n" 3115 "layout (location=3) out mediump vec4 d[1]; \n" 3116 "void main() { \n" 3117 " a = vec4(0, 1, 0, 1); \n" 3118 " b = vec4(0, 1, 0, 1); \n" 3119 " c = vec4(0, 1, 0, 1); \n" 3120 " d[0] = vec4(0, 1, 0, 1); \n" 3121 "}"; 3122 } 3123 3124 virtual long Run() 3125 { 3126 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 3127 glBindAttribLocation(program, 0, "position"); 3128 glLinkProgram(program); 3129 3130 long error = NO_ERROR; 3131 3132 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error); 3133 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error); 3134 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error); 3135 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error); 3136 3137 std::map<std::string, GLuint> indicesI; 3138 std::map<std::string, GLuint> indicesO; 3139 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error); 3140 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error); 3141 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error); 3142 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error); 3143 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error); 3144 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error); 3145 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error); 3146 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error); 3147 3148 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error); 3149 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error); 3150 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c", error); 3151 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error); 3152 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error); 3153 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error); 3154 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error); 3155 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error); 3156 3157 std::map<std::string, GLint> locationsI; 3158 std::map<std::string, GLint> locationsO; 3159 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error); 3160 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error); 3161 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error); 3162 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error); 3163 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error); 3164 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error); 3165 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error); 3166 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error); 3167 3168 GLenum props[] = { GL_NAME_LENGTH, 3169 GL_TYPE, 3170 GL_ARRAY_SIZE, 3171 GL_REFERENCED_BY_COMPUTE_SHADER, 3172 GL_REFERENCED_BY_FRAGMENT_SHADER, 3173 GL_REFERENCED_BY_VERTEX_SHADER }; 3174 GLint expected[] = { 2, 35666, 1, 0, 0, 1 }; 3175 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error); 3176 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error); 3177 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error); 3178 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected, error); 3179 GLint expected3[] = { 2, 35666, 1, 0, 1, 0 }; 3180 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error); 3181 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error); 3182 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error); 3183 GLint expected4[] = { 5, 35666, 1, 0, 1, 0 }; 3184 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error); 3185 3186 glDeleteProgram(program); 3187 return error; 3188 } 3189}; 3190 3191class OutputBuiltIn : public SimpleShaders 3192{ 3193 3194 virtual std::string Title() 3195 { 3196 return "Output Built-ins Test"; 3197 } 3198 3199 virtual std::string ShadersDesc() 3200 { 3201 return "fragment shader using built-in variables and a fallthrough vertex shader"; 3202 } 3203 3204 virtual std::string Expectations() 3205 { 3206 return ".\n\n In this case we ask for information about built-in variables for the output interface."; 3207 } 3208 3209 virtual std::string FragmentShader() 3210 { 3211 return "#version 310 es \n" 3212 "void main(void) \n" 3213 "{ \n" 3214 " gl_FragDepth = 0.1; \n" 3215 "}"; 3216 } 3217 3218 virtual long Run() 3219 { 3220 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true); 3221 3222 long error = NO_ERROR; 3223 3224 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error); 3225 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 13, error); 3226 3227 std::map<std::string, GLuint> indices; 3228 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error); 3229 3230 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error); 3231 3232 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error); 3233 3234 GLenum props[] = { GL_NAME_LENGTH, 3235 GL_TYPE, 3236 GL_ARRAY_SIZE, 3237 GL_REFERENCED_BY_COMPUTE_SHADER, 3238 GL_REFERENCED_BY_FRAGMENT_SHADER, 3239 GL_REFERENCED_BY_VERTEX_SHADER, 3240 GL_LOCATION }; 3241 GLint expected[] = { 13, 5126, 1, 0, 1, 0, -1 }; 3242 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], DE_LENGTH_OF_ARRAY(props), 3243 props, DE_LENGTH_OF_ARRAY(expected), expected, error); 3244 3245 glDeleteProgram(program); 3246 return error; 3247 } 3248}; 3249 3250class QueryNotUsed : public SimpleShaders 3251{ 3252 3253 virtual std::string Title() 3254 { 3255 return "Query Not Used Test"; 3256 } 3257 3258 virtual std::string PassCriteria() 3259 { 3260 return "Data from queries matches the not used program."; 3261 } 3262 3263 virtual std::string Purpose() 3264 { 3265 return "Verify that program parameter works correctly and proper program is queried when different program is " 3266 "used."; 3267 } 3268 3269 virtual std::string Method() 3270 { 3271 return "Create 2 programs, use one of them and query the other, verify the results."; 3272 } 3273 3274 virtual std::string VertexShader2() 3275 { 3276 return "#version 310 es \n" 3277 "in mediump vec4 p; \n" 3278 "void main(void) \n" 3279 "{ \n" 3280 " gl_Position = p; \n" 3281 "}"; 3282 } 3283 3284 virtual std::string FragmentShader2() 3285 { 3286 return "#version 310 es \n" 3287 "out mediump vec4 c; \n" 3288 "void main() { \n" 3289 " c = vec4(0., 1., 0., 1.); \n" 3290 "}"; 3291 } 3292 3293 virtual long Run() 3294 { 3295 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 3296 LinkProgram(program); 3297 3298 GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false); 3299 LinkProgram(program2); 3300 glUseProgram(program2); 3301 3302 long error = NO_ERROR; 3303 3304 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error); 3305 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error); 3306 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error); 3307 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error); 3308 3309 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error); 3310 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error); 3311 3312 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error); 3313 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error); 3314 3315 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error); 3316 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error); 3317 3318 GLenum props[] = { GL_NAME_LENGTH, 3319 GL_TYPE, 3320 GL_ARRAY_SIZE, 3321 GL_REFERENCED_BY_COMPUTE_SHADER, 3322 GL_REFERENCED_BY_FRAGMENT_SHADER, 3323 GL_REFERENCED_BY_VERTEX_SHADER, 3324 GL_LOCATION }; 3325 GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 }; 3326 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, DE_LENGTH_OF_ARRAY(props), props, 3327 DE_LENGTH_OF_ARRAY(expected), expected, error); 3328 3329 GLenum props2[] = { GL_NAME_LENGTH, 3330 GL_TYPE, 3331 GL_ARRAY_SIZE, 3332 GL_REFERENCED_BY_COMPUTE_SHADER, 3333 GL_REFERENCED_BY_FRAGMENT_SHADER, 3334 GL_REFERENCED_BY_VERTEX_SHADER, 3335 GL_LOCATION }; 3336 GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 }; 3337 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error); 3338 3339 glDeleteProgram(program); 3340 glDeleteProgram(program2); 3341 return error; 3342 } 3343}; 3344 3345class RelinkFailure : public SimpleShaders 3346{ 3347 3348 virtual std::string Title() 3349 { 3350 return "Relink Failure Test"; 3351 } 3352 3353 virtual std::string PassCriteria() 3354 { 3355 return "INVALID_OPERATION is generated when asking for locations after failed link."; 3356 } 3357 3358 virtual std::string Purpose() 3359 { 3360 return "Verify that queries behave correctly after failed relink of a program."; 3361 } 3362 3363 virtual std::string Method() 3364 { 3365 return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when " 3366 "asking for locations."; 3367 } 3368 3369 virtual std::string VertexShader() 3370 { 3371 return "#version 310 es \n" 3372 "in mediump vec4 position; \n" 3373 "in mediump vec3 pos; \n" 3374 "void main(void) \n" 3375 "{ \n" 3376 " gl_Position = position + vec4(pos, 1.); \n" 3377 "}"; 3378 } 3379 3380 virtual long Run() 3381 { 3382 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false); 3383 glBindAttribLocation(program, 0, "position"); 3384 glBindAttribLocation(program, 1, "pos"); 3385 LinkProgram(program); 3386 3387 long error = NO_ERROR; 3388 3389 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error); 3390 glUseProgram(program); 3391 3392 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1), 3393 tcu::Vec4(1, -1, 0, 1) }; 3394 GLuint vao, vbuf; 3395 glGenVertexArrays(1, &vao); 3396 glBindVertexArray(vao); 3397 glGenBuffers(1, &vbuf); 3398 glBindBuffer(GL_ARRAY_BUFFER, vbuf); 3399 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW); 3400 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0); 3401 glEnableVertexAttribArray(0); 3402 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 3403 3404 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3405 glDisableVertexAttribArray(0); 3406 glDeleteVertexArrays(1, &vao); 3407 glBindBuffer(GL_ARRAY_BUFFER, 0); 3408 glDeleteBuffers(1, &vbuf); 3409 3410 glBindAttribLocation(program, 0, "pos"); 3411 glBindAttribLocation(program, 0, "position"); 3412 const char* varyings[2] = { "q", "z" }; 3413 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS); 3414 LinkProgram(program); 3415 3416 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error); 3417 ExpectError(GL_INVALID_OPERATION, error); 3418 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error); 3419 ExpectError(GL_INVALID_OPERATION, error); 3420 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error); 3421 ExpectError(GL_INVALID_OPERATION, error); 3422 3423 glDeleteProgram(program); 3424 return error; 3425 } 3426}; 3427 3428class LinkFailure : public SimpleShaders 3429{ 3430 3431 virtual std::string Title() 3432 { 3433 return "Link Failure Test"; 3434 } 3435 3436 virtual std::string PassCriteria() 3437 { 3438 return "INVALID_OPERATION is generated when asking for locations after failed link."; 3439 } 3440 3441 virtual std::string Purpose() 3442 { 3443 return "Verify that queries behave correctly after failed relink of a program with changed sources."; 3444 } 3445 3446 virtual std::string Method() 3447 { 3448 return "Create a program, use it, relink with failure using different sources and then \n" 3449 "verify that INVALID_OPERATION is returned when asking for locations."; 3450 } 3451 3452 virtual const char* VertexShader_prop() 3453 { 3454 return "#version 310 es \n" 3455 "in mediump vec4 posit; \n" 3456 "in mediump vec4 p; \n" 3457 "void main(void) \n" 3458 "{ \n" 3459 " gl_Position = p + posit; \n" 3460 "}"; 3461 } 3462 3463 virtual const char* FragmentShader_prop() 3464 { 3465 return "#version 310 es \n" 3466 "out mediump vec4 color; \n" 3467 "void main() { \n" 3468 " color = vec4(0., 1., 0., 1.); \n" 3469 "}"; 3470 } 3471 3472 virtual const char* VertexShader_fail() 3473 { 3474 return "#version 310 es \n" 3475 "in mediump vec4 position; \n" 3476 "void main(void) \n" 3477 "{ \n" 3478 " gl_Position = position; \n" 3479 "}"; 3480 } 3481 3482 virtual long Run() 3483 { 3484 const GLuint program = glCreateProgram(); 3485 const char* src_vs = VertexShader_prop(); 3486 const char* src_fs = FragmentShader_prop(); 3487 const char* src_vsh = VertexShader_fail(); 3488 3489 GLuint sh1 = glCreateShader(GL_VERTEX_SHADER); 3490 glAttachShader(program, sh1); 3491 glDeleteShader(sh1); 3492 glShaderSource(sh1, 1, &src_vs, NULL); 3493 glCompileShader(sh1); 3494 3495 GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER); 3496 glAttachShader(program, sh2); 3497 glDeleteShader(sh2); 3498 glShaderSource(sh2, 1, &src_fs, NULL); 3499 glCompileShader(sh2); 3500 3501 glBindAttribLocation(program, 0, "p"); 3502 glBindAttribLocation(program, 1, "posit"); 3503 LinkProgram(program); 3504 3505 long error = NO_ERROR; 3506 3507 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error); 3508 glUseProgram(program); 3509 3510 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1), 3511 tcu::Vec4(1, -1, 0, 1) }; 3512 GLuint vao, vbuf; 3513 glGenVertexArrays(1, &vao); 3514 glBindVertexArray(vao); 3515 glGenBuffers(1, &vbuf); 3516 glBindBuffer(GL_ARRAY_BUFFER, vbuf); 3517 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW); 3518 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0); 3519 glEnableVertexAttribArray(0); 3520 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 3521 3522 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3523 glDisableVertexAttribArray(0); 3524 glDeleteVertexArrays(1, &vao); 3525 glBindBuffer(GL_ARRAY_BUFFER, 0); 3526 glDeleteBuffers(1, &vbuf); 3527 3528 glDetachShader(program, sh1); 3529 GLuint vsh = glCreateShader(GL_VERTEX_SHADER); 3530 glAttachShader(program, vsh); 3531 glDeleteShader(vsh); 3532 glShaderSource(vsh, 1, &src_vsh, NULL); 3533 glCompileShader(vsh); 3534 const char* varyings[2] = { "q", "z" }; 3535 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS); 3536 LinkProgram(program); 3537 3538 GLint res; 3539 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error); 3540 ExpectError(GL_INVALID_OPERATION, error); 3541 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res); 3542 if (res != 0 && res != 1) 3543 { 3544 m_context.getTestContext().getLog() 3545 << tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res 3546 << tcu::TestLog::EndMessage; 3547 error = ERROR; 3548 } 3549 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res); 3550 if (res != 0 && res != 9) 3551 { 3552 m_context.getTestContext().getLog() 3553 << tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res 3554 << tcu::TestLog::EndMessage; 3555 error = ERROR; 3556 } 3557 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error); 3558 ExpectError(GL_INVALID_OPERATION, error); 3559 3560 glDeleteProgram(program); 3561 return error; 3562 } 3563}; 3564} 3565 3566ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(glcts::Context& context) 3567 : TestCaseGroup(context, "program_interface_query", "") 3568{ 3569} 3570 3571ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void) 3572{ 3573} 3574 3575void ProgramInterfaceQueryTests::init() 3576{ 3577 using namespace glcts; 3578 addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>)); 3579 addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>)); 3580 addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>)); 3581 addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>)); 3582 addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>)); 3583 addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>)); 3584 addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>)); 3585 addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>)); 3586 addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>)); 3587 addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>)); 3588 addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>)); 3589 addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>)); 3590 addChild( 3591 new TestSubcase(m_context, "atomic-counters-one-buffer", TestSubcase::Create<AtomicCounterSimpleOneBuffer>)); 3592 addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>)); 3593 addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>)); 3594 addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>)); 3595 addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>)); 3596 addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>)); 3597 addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>)); 3598 addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>)); 3599 addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>)); 3600 addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>)); 3601 addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>)); 3602 addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>)); 3603 addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>)); 3604 addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>)); 3605 addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>)); 3606 addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>)); 3607 addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>)); 3608 addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>)); 3609} 3610} 3611