1 /*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2015-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 /** 25 * \file gl4cKHRDebugTests.cpp 26 * \brief Implements conformance tests for "KHR Debug" functionality. 27 */ /*-------------------------------------------------------------------*/ 28 29 #include "gl4cKHRDebugTests.hpp" 30 31 #include "gluPlatform.hpp" 32 #include "gluRenderConfig.hpp" 33 #include "gluRenderContext.hpp" 34 #include "gluStrUtil.hpp" 35 #include "glwEnums.hpp" 36 #include "glwFunctions.hpp" 37 #include "tcuCommandLine.hpp" 38 #include "tcuTestLog.hpp" 39 // 40 //#include <string> 41 42 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0 43 44 #if DEBUG_ENBALE_MESSAGE_CALLBACK 45 //#include <iomanip> 46 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 47 48 using namespace glw; 49 50 namespace gl4cts 51 { 52 namespace KHRDebug 53 { 54 /** Macro, verifies generated error, logs error message and throws failure 55 * 56 * @param expected_error Expected error value 57 * @param error_message Message logged if generated error is not the expected one 58 **/ 59 #define CHECK_ERROR(expected_error, error_message) \ 60 { \ 61 GLenum generated_error = m_gl->getError(); \ 62 \ 63 if (expected_error != generated_error) \ 64 { \ 65 m_context.getTestContext().getLog() \ 66 << tcu::TestLog::Message << "File: " << __FILE__ << ", line: " << __LINE__ \ 67 << ". Got wrong error: " << glu::getErrorStr(generated_error) \ 68 << ", expected: " << glu::getErrorStr(expected_error) << ", message: " << error_message \ 69 << tcu::TestLog::EndMessage; \ 70 TCU_FAIL("Invalid error generated"); \ 71 } \ 72 } 73 74 /** Pop all groups from stack 75 * 76 * @param gl GL functions 77 **/ 78 void cleanGroupStack(const Functions* gl) 79 { 80 while (1) 81 { 82 gl->popDebugGroup(); 83 84 const GLenum err = gl->getError(); 85 86 if (GL_STACK_UNDERFLOW == err) 87 { 88 break; 89 } 90 91 GLU_EXPECT_NO_ERROR(err, "PopDebugGroup"); 92 } 93 } 94 95 /** Extracts all messages from log 96 * 97 * @param gl GL functions 98 **/ 99 void cleanMessageLog(const Functions* gl) 100 { 101 static const GLuint count = 16; 102 103 while (1) 104 { 105 GLuint ret = gl->getDebugMessageLog(count /* count */, 0 /* bufSize */, 0 /* sources */, 0 /* types */, 106 0 /* ids */, 0 /* severities */, 0 /* lengths */, 0 /* messageLog */); 107 108 GLU_EXPECT_NO_ERROR(gl->getError(), "GetDebugMessageLog"); 109 110 if (0 == ret) 111 { 112 break; 113 } 114 } 115 } 116 117 /** Fill stack of groups 118 * 119 * @param gl GL functions 120 **/ 121 void fillGroupStack(const Functions* gl) 122 { 123 static const GLchar message[] = "Foo"; 124 static const GLsizei length = (GLsizei)(sizeof(message) / sizeof(message[0])); 125 126 while (1) 127 { 128 gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */, 129 message /* message */); 130 131 const GLenum err = gl->getError(); 132 133 if (GL_STACK_OVERFLOW == err) 134 { 135 break; 136 } 137 138 GLU_EXPECT_NO_ERROR(err, "PopDebugGroup"); 139 } 140 } 141 142 /** Constructor 143 * Creates and set as current new context that should be used by test. 144 * 145 * @param context Test context 146 * @param is_debug Selects if debug or non-debug context should be created 147 **/ 148 TestBase::TestBase(deqp::Context& context, bool is_debug) 149 : m_gl(0), m_is_debug(is_debug), m_rc(0), m_test_base_context(context), m_orig_rc(0) 150 { 151 /* Nothing to be done here */ 152 } 153 154 /** Destructor 155 * Destroys context used by test and set original context as current 156 **/ 157 TestBase::~TestBase() 158 { 159 if (0 != m_rc) 160 { 161 done(); 162 } 163 } 164 165 /** Initialize rendering context 166 **/ 167 void TestBase::init() 168 { 169 if (true == m_is_debug) 170 { 171 initDebug(); 172 } 173 else 174 { 175 initNonDebug(); 176 } 177 178 m_orig_rc = &m_test_base_context.getRenderContext(); 179 m_test_base_context.setRenderContext(m_rc); 180 181 /* Get functions */ 182 m_gl = &m_rc->getFunctions(); 183 } 184 185 /** Prepares debug context 186 **/ 187 void TestBase::initDebug() 188 { 189 tcu::Platform& platform = m_test_base_context.getTestContext().getPlatform(); 190 glu::RenderConfig renderCfg( 191 glu::ContextType(m_test_base_context.getRenderContext().getType().getAPI(), glu::CONTEXT_DEBUG)); 192 193 const tcu::CommandLine& commandLine = m_test_base_context.getTestContext().getCommandLine(); 194 parseRenderConfig(&renderCfg, commandLine); 195 196 if (commandLine.getSurfaceType() == tcu::SURFACETYPE_WINDOW) 197 { 198 renderCfg.surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC; 199 } 200 else 201 { 202 throw tcu::NotSupportedError("Test not supported in non-windowed context"); 203 } 204 205 m_rc = createRenderContext(platform, commandLine, renderCfg); 206 m_rc->makeCurrent(); 207 } 208 209 /** Prepares non-debug context 210 **/ 211 void TestBase::initNonDebug() 212 { 213 tcu::Platform& platform = m_test_base_context.getTestContext().getPlatform(); 214 glu::RenderConfig renderCfg( 215 glu::ContextType(m_test_base_context.getRenderContext().getType().getAPI(), glu::ContextFlags(0))); 216 217 const tcu::CommandLine& commandLine = m_test_base_context.getTestContext().getCommandLine(); 218 parseRenderConfig(&renderCfg, commandLine); 219 220 if (commandLine.getSurfaceType() == tcu::SURFACETYPE_WINDOW) 221 { 222 renderCfg.surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC; 223 } 224 else 225 { 226 throw tcu::NotSupportedError("Test not supported in non-windowed context"); 227 } 228 229 m_rc = createRenderContext(platform, commandLine, renderCfg); 230 m_rc->makeCurrent(); 231 } 232 233 /** Finalize rendering context 234 **/ 235 void TestBase::done() 236 { 237 /* Delete context used by test */ 238 m_test_base_context.setRenderContext(m_orig_rc); 239 240 delete m_rc; 241 242 /* Switch back to original context */ 243 m_test_base_context.getRenderContext().makeCurrent(); 244 245 m_rc = 0; 246 m_gl = 0; 247 } 248 249 /** Constructor 250 * 251 * @param context Test context 252 * @param is_debug Selects if debug or non-debug context should be used 253 * @param name Name of test 254 **/ 255 APIErrorsTest::APIErrorsTest(deqp::Context& context, bool is_debug, const GLchar* name) 256 : TestCase(context, name, "Verifies that errors are generated as expected"), TestBase(context, is_debug) 257 { 258 /* Nothing to be done */ 259 } 260 261 /** Execute test 262 * 263 * @return tcu::TestNode::STOP 264 **/ 265 tcu::TestNode::IterateResult APIErrorsTest::iterate() 266 { 267 /* Initialize rendering context */ 268 TestBase::init(); 269 270 /* Get maximum label length */ 271 GLint max_label = 0; 272 273 m_gl->getIntegerv(GL_MAX_LABEL_LENGTH, &max_label); 274 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 275 276 /* Prepare too long label */ 277 std::vector<GLchar> too_long_label; 278 279 too_long_label.resize(max_label + 2); 280 281 for (GLint i = 0; i <= max_label; ++i) 282 { 283 too_long_label[i] = 'f'; 284 } 285 286 too_long_label[max_label + 1] = 0; 287 288 /* Get maximum message length */ 289 GLint max_length = 0; 290 291 m_gl->getIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &max_length); 292 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 293 294 /* Prepare too long message */ 295 std::vector<GLchar> too_long_message; 296 297 too_long_message.resize(max_length + 2); 298 299 for (GLint i = 0; i <= max_length; ++i) 300 { 301 too_long_message[i] = 'f'; 302 } 303 304 too_long_message[max_length + 1] = 0; 305 306 /* Get maximum number of groups on stack */ 307 GLint max_groups = 0; 308 309 m_gl->getIntegerv(GL_MAX_DEBUG_GROUP_STACK_DEPTH, &max_groups); 310 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 311 312 /* 313 * DebugMessageControl function should generate: 314 * - INVALID_ENUM when <source> is invalid; 315 * - INVALID_ENUM when <type> is invalid; 316 * - INVALID_ENUM when <severity> is invalid; 317 * - INVALID_VALUE when <count> is negative; 318 * - INVALID_OPERATION when <count> is not zero and <source> is DONT_CARE; 319 * - INVALID_OPERATION when <count> is not zero and <type> is DONT_CARE; 320 * - INVALID_OPERATION when <count> is not zero and <severity> is not 321 * DONT_CARE. 322 */ 323 { 324 static const GLuint ids[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; 325 static const GLsizei n_ids = (GLsizei)(sizeof(ids) / sizeof(ids[0])); 326 327 m_gl->debugMessageControl(GL_ARRAY_BUFFER /* source */, GL_DEBUG_TYPE_ERROR /* type */, 328 GL_DEBUG_SEVERITY_LOW /* severity */, 0 /* count */, 0 /* ids */, 329 GL_TRUE /* enabled */); 330 CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <source> set to GL_ARRAY_BUFFER"); 331 332 m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_ARRAY_BUFFER /* type */, 333 GL_DEBUG_SEVERITY_LOW /* severity */, 0 /* count */, 0 /* ids */, 334 GL_TRUE /* enabled */); 335 CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <type> set to GL_ARRAY_BUFFER"); 336 337 m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */, 338 GL_ARRAY_BUFFER /* severity */, 0 /* count */, 0 /* ids */, GL_TRUE /* enabled */); 339 CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <severity> set to GL_ARRAY_BUFFER"); 340 341 m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */, 342 GL_DEBUG_SEVERITY_LOW /* severity */, -1 /* count */, ids /* ids */, 343 GL_TRUE /* enabled */); 344 CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageControl with <count> set to -1"); 345 346 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */, 347 GL_DONT_CARE /* severity */, n_ids /* count */, ids /* ids */, GL_TRUE /* enabled */); 348 CHECK_ERROR(GL_INVALID_OPERATION, "DebugMessageControl with <source> set to GL_DONT_CARE and non zero <count>"); 349 350 m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DONT_CARE /* type */, 351 GL_DONT_CARE /* severity */, n_ids /* count */, ids /* ids */, GL_TRUE /* enabled */); 352 CHECK_ERROR(GL_INVALID_OPERATION, "DebugMessageControl with <type> set to GL_DONT_CARE and non zero <count>"); 353 354 m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */, 355 GL_DEBUG_SEVERITY_LOW /* severity */, n_ids /* count */, ids /* ids */, 356 GL_TRUE /* enabled */); 357 CHECK_ERROR(GL_INVALID_OPERATION, 358 "DebugMessageControl with <severity> set to GL_DEBUG_SEVERITY_LOW and non zero <count>"); 359 } 360 361 /* 362 * GetDebugMessageLog function should generate: 363 * - INVALID_VALUE when <bufSize> is negative and messageLog is not NULL. 364 */ 365 { 366 static const GLsizei bufSize = 32; 367 static const GLuint count = 4; 368 369 GLenum ids[count]; 370 GLsizei lengths[count]; 371 GLchar messageLog[bufSize]; 372 GLenum types[count]; 373 GLenum severities[count]; 374 GLenum sources[count]; 375 376 m_gl->getDebugMessageLog(count /* count */, -1 /* bufSize */, sources, types, ids, severities, lengths, 377 messageLog); 378 CHECK_ERROR(GL_INVALID_VALUE, "GetDebugMessageLog with <bufSize> set to -1"); 379 } 380 381 /* 382 * DebugMessageInsert function should generate: 383 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or 384 * DEBUG_SOURCE_THIRD_PARTY; 385 * - INVALID_ENUM when <type> is invalid; 386 * - INVALID_ENUM when <severity> is invalid; 387 * - INVALID_VALUE when length of string <buf> is not less than 388 * MAX_DEBUG_MESSAGE_LENGTH. 389 */ 390 { 391 static const GLchar message[] = "Foo"; 392 static const GLsizei length = (GLsizei)(sizeof(message) / sizeof(message[0])); 393 394 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */, 395 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, length /* length */, 396 message /* message */); 397 CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <source> set to GL_DEBUG_SOURCE_API"); 398 399 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_ARRAY_BUFFER /* type */, 0 /* id */, 400 GL_DEBUG_SEVERITY_LOW /* severity */, length /* length */, message /* message */); 401 CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <type> set to GL_ARRAY_BUFFER"); 402 403 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */, 404 0 /* id */, GL_ARRAY_BUFFER /* severity */, length /* length */, 405 message /* message */); 406 CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <severity> set to GL_ARRAY_BUFFER"); 407 408 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */, 409 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, max_length + 1 /* length */, 410 message /* message */); 411 CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageInsert with <length> set to GL_MAX_DEBUG_MESSAGE_LENGTH + 1"); 412 413 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */, 414 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, -1 /* length */, 415 &too_long_message[0] /* message */); 416 CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageInsert with too long message"); 417 } 418 419 /* 420 * PushDebugGroup function should generate: 421 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or 422 * DEBUG_SOURCE_THIRD_PARTY; 423 * - INVALID_VALUE when length of string <message> is not less than 424 * MAX_DEBUG_MESSAGE_LENGTH; 425 * - STACK_OVERFLOW when stack contains MAX_DEBUG_GROUP_STACK_DEPTH entries. 426 */ 427 { 428 static const GLchar message[] = "Foo"; 429 static const GLsizei length = (GLsizei)(sizeof(message) / sizeof(message[0])); 430 431 m_gl->pushDebugGroup(GL_DEBUG_SOURCE_API /* source */, 1 /* id */, length /* length */, message /* message */); 432 CHECK_ERROR(GL_INVALID_ENUM, "PushDebugGroup with <source> set to GL_DEBUG_SOURCE_API"); 433 434 m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, max_length + 1 /* length */, 435 message /* message */); 436 CHECK_ERROR(GL_INVALID_VALUE, "PushDebugGroup with <length> set to GL_MAX_DEBUG_MESSAGE_LENGTH + 1"); 437 438 m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, -1 /* length */, 439 &too_long_message[0] /* message */); 440 CHECK_ERROR(GL_INVALID_VALUE, "PushDebugGroup with too long message"); 441 442 /* Clean stack */ 443 cleanGroupStack(m_gl); 444 445 /* Fill stack */ 446 for (GLint i = 0; i < max_groups - 1; ++i) 447 { 448 m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */, 449 message /* message */); 450 GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup"); 451 } 452 453 /* Overflow stack */ 454 m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */, 455 message /* message */); 456 CHECK_ERROR(GL_STACK_OVERFLOW, "PushDebugGroup called GL_MAX_DEBUG_GROUP_STACK_DEPTH times"); 457 458 /* Clean stack */ 459 cleanGroupStack(m_gl); 460 } 461 462 /* 463 * PopDebugGroup function should generate: 464 * - STACK_UNDERFLOW when stack contains no entries. 465 */ 466 { 467 fillGroupStack(m_gl); 468 469 for (GLint i = 0; i < max_groups - 1; ++i) 470 { 471 m_gl->popDebugGroup(); 472 473 GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup"); 474 } 475 476 m_gl->popDebugGroup(); 477 CHECK_ERROR(GL_STACK_UNDERFLOW, "PopDebugGroup called GL_MAX_DEBUG_GROUP_STACK_DEPTH times"); 478 } 479 480 /* 481 * ObjectLabel function should generate: 482 * - INVALID_ENUM when <identifier> is invalid; 483 * - INVALID_VALUE when if <name> is not valid object name of type specified by 484 * <identifier>; 485 * - INVALID_VALUE when length of string <label> is not less than 486 * MAX_LABEL_LENGTH. 487 */ 488 { 489 static const GLchar label[] = "Foo"; 490 static const GLsizei length = (GLsizei)(sizeof(label) / sizeof(label[0])); 491 492 GLuint texture_id = 0; 493 GLuint invalid_id = 1; 494 m_gl->genTextures(1, &texture_id); 495 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenTextures"); 496 m_gl->bindTexture(GL_TEXTURE_BUFFER, texture_id); 497 GLU_EXPECT_NO_ERROR(m_gl->getError(), "BindTexture"); 498 499 try 500 { 501 m_gl->objectLabel(GL_TEXTURE_BUFFER /* identifier */, texture_id /* name */, length /* length */, 502 label /* label */); 503 CHECK_ERROR(GL_INVALID_ENUM, "ObjectLabel with <identifier> set to GL_TEXTURE_BUFFER"); 504 505 while (GL_TRUE == m_gl->isTexture(invalid_id)) 506 { 507 invalid_id += 1; 508 } 509 510 m_gl->objectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, length /* length */, 511 label /* label */); 512 CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with <name> set to not generated value"); 513 514 m_gl->objectLabel(GL_TEXTURE /* identifier */, texture_id /* name */, max_label + 1 /* length */, 515 label /* label */); 516 CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with <label> set to MAX_LABEL_LENGTH + 1"); 517 518 m_gl->objectLabel(GL_TEXTURE /* identifier */, texture_id /* name */, -1 /* length */, 519 &too_long_label[0] /* label */); 520 CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with too long label"); 521 } 522 catch (const std::exception& exc) 523 { 524 m_gl->deleteTextures(1, &texture_id); 525 TCU_FAIL(exc.what()); 526 } 527 528 m_gl->deleteTextures(1, &texture_id); 529 } 530 531 /* 532 * GetObjectLabel function should generate: 533 * - INVALID_ENUM when <identifier> is invalid; 534 * - INVALID_VALUE when if <name> is not valid object name of type specified by 535 * <identifier>; 536 * - INVALID_VALUE when <bufSize> is negative. 537 */ 538 { 539 static const GLsizei bufSize = 32; 540 541 GLchar label[bufSize]; 542 GLsizei length = 0; 543 544 GLuint texture_id = 0; 545 GLuint invalid_id = 1; 546 m_gl->genTextures(1, &texture_id); 547 m_gl->bindTexture(GL_TEXTURE_2D, texture_id); 548 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenTextures"); 549 550 try 551 { 552 m_gl->getObjectLabel(GL_TEXTURE_BUFFER /* identifier */, texture_id /* name */, bufSize /* bufSize */, 553 &length /* length */, label /* label */); 554 CHECK_ERROR(GL_INVALID_ENUM, "GetObjectLabel with <identifier> set to GL_TEXTURE_BUFFER"); 555 556 while (GL_TRUE == m_gl->isTexture(invalid_id)) 557 { 558 invalid_id += 1; 559 } 560 561 m_gl->getObjectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, bufSize /* bufSize */, 562 &length /* length */, label /* label */); 563 CHECK_ERROR(GL_INVALID_VALUE, "GetObjectLabel with <name> set to not generated value"); 564 565 m_gl->getObjectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, -1 /* bufSize */, 566 &length /* length */, label /* label */); 567 CHECK_ERROR(GL_INVALID_VALUE, "GetObjectLabel with <bufSize> set to -1"); 568 } 569 catch (const std::exception& exc) 570 { 571 m_gl->deleteTextures(1, &texture_id); 572 TCU_FAIL(exc.what()); 573 } 574 575 m_gl->deleteTextures(1, &texture_id); 576 } 577 578 /* 579 * ObjectPtrLabel function should generate: 580 * - INVALID_VALUE when <ptr> is not the name of sync object; 581 * - INVALID_VALUE when length of string <label> is not less than 582 * MAX_LABEL_LENGTH. 583 */ 584 { 585 static const GLchar label[] = "Foo"; 586 static const GLsizei length = (GLsizei)(sizeof(label) / sizeof(label[0])); 587 588 GLsync sync_id = 0; 589 GLsync invalid_id = 0; 590 sync_id = m_gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 591 GLU_EXPECT_NO_ERROR(m_gl->getError(), "FenceSync"); 592 593 try 594 { 595 while (GL_TRUE == m_gl->isSync(invalid_id)) 596 { 597 invalid_id = (GLsync)(((unsigned long long)invalid_id) + 1); 598 } 599 600 m_gl->objectPtrLabel(invalid_id /* name */, length /* length */, label /* label */); 601 CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with <ptr> set to not generated value"); 602 603 m_gl->objectPtrLabel(sync_id /* name */, max_label + 1 /* length */, label /* label */); 604 CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with <length> set to MAX_LABEL_LENGTH + 1"); 605 606 m_gl->objectPtrLabel(sync_id /* name */, -1 /* length */, &too_long_label[0] /* label */); 607 CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with too long label"); 608 } 609 catch (const std::exception& exc) 610 { 611 m_gl->deleteSync(sync_id); 612 TCU_FAIL(exc.what()); 613 } 614 615 m_gl->deleteSync(sync_id); 616 } 617 618 /* 619 * GetObjectPtrLabel function should generate: 620 * - INVALID_VALUE when <ptr> is not the name of sync object; 621 * - INVALID_VALUE when <bufSize> is negative. 622 */ 623 { 624 static const GLsizei bufSize = 32; 625 626 GLchar label[bufSize]; 627 GLsizei length = 0; 628 629 GLsync sync_id = 0; 630 GLsync invalid_id = 0; 631 sync_id = m_gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 632 GLU_EXPECT_NO_ERROR(m_gl->getError(), "FenceSync"); 633 634 try 635 { 636 while (GL_TRUE == m_gl->isSync(invalid_id)) 637 { 638 invalid_id = (GLsync)(((unsigned long long)invalid_id) + 1); 639 } 640 641 m_gl->getObjectPtrLabel(invalid_id /* name */, bufSize /* bufSize */, &length /* length */, 642 label /* label */); 643 CHECK_ERROR(GL_INVALID_VALUE, "GetObjectPtrLabel with <ptr> set to not generated value"); 644 645 m_gl->getObjectPtrLabel(sync_id /* name */, -1 /* bufSize */, &length /* length */, label /* label */); 646 CHECK_ERROR(GL_INVALID_VALUE, "GetObjectPtrLabel with <bufSize> set to -1"); 647 } 648 catch (const std::exception& exc) 649 { 650 m_gl->deleteSync(sync_id); 651 TCU_FAIL(exc.what()); 652 } 653 654 m_gl->deleteSync(sync_id); 655 } 656 657 /* 658 * GetPointerv function should generate: 659 * - INVALID_ENUM when <pname> is invalid. 660 **/ 661 { 662 GLuint uint; 663 GLuint* uint_ptr = &uint; 664 665 m_gl->getPointerv(GL_ARRAY_BUFFER, (GLvoid**)&uint_ptr); 666 CHECK_ERROR(GL_INVALID_ENUM, "GetPointerv with <pname> set to GL_ARRAY_BUFFER"); 667 } 668 669 /* Set result */ 670 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 671 672 /* Done */ 673 TestBase::done(); 674 675 return tcu::TestNode::STOP; 676 } 677 678 /** Constructor 679 * 680 * @param context Test context 681 * @param is_debug Selects if debug or non-debug context should be used 682 * @param name Name of test 683 **/ 684 LabelsTest::LabelsTest(deqp::Context& context, bool is_debug, const GLchar* name) 685 : TestCase(context, name, "Verifies that labels can be assigned and queried"), TestBase(context, is_debug) 686 { 687 /* Nothing to be done */ 688 } 689 690 /** Represnets case for LabelsTest **/ 691 struct labelsTestCase 692 { 693 GLenum m_identifier; 694 GLuint (*m_create)(const glw::Functions* gl, const glu::RenderContext*); 695 GLvoid (*m_destroy)(const glw::Functions* gl, GLuint id); 696 const GLchar* m_name; 697 }; 698 699 /** Execute test 700 * 701 * @return tcu::TestNode::STOP 702 **/ 703 tcu::TestNode::IterateResult LabelsTest::iterate() 704 { 705 static const labelsTestCase test_cases[] = { 706 { GL_BUFFER, createBuffer, deleteBuffer, "Buffer" }, 707 { GL_FRAMEBUFFER, createFramebuffer, deleteFramebuffer, "Framebuffer" }, 708 { GL_PROGRAM, createProgram, deleteProgram, "Program" }, 709 { GL_PROGRAM_PIPELINE, createProgramPipeline, deleteProgramPipeline, "ProgramPipeline" }, 710 { GL_QUERY, createQuery, deleteQuery, "Query" }, 711 { GL_RENDERBUFFER, createRenderbuffer, deleteRenderbuffer, "Renderbuffer" }, 712 { GL_SAMPLER, createSampler, deleteSampler, "Sampler" }, 713 { GL_SHADER, createShader, deleteShader, "Shader" }, 714 { GL_TEXTURE, createTexture, deleteTexture, "Texture" }, 715 { GL_TRANSFORM_FEEDBACK, createTransformFeedback, deleteTransformFeedback, "TransformFeedback" }, 716 { GL_VERTEX_ARRAY, createVertexArray, deleteVertexArray, "VertexArray" }, 717 }; 718 719 static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); 720 721 static const GLsizei bufSize = 32; 722 static const GLchar label[] = "foo"; 723 static const GLsizei label_length = (GLsizei)(sizeof(label) / sizeof(label[0]) - 1); 724 725 /* Initialize render context */ 726 TestBase::init(); 727 728 /* For each test case */ 729 for (size_t test_case_index = 0; test_case_index < n_test_cases; ++test_case_index) 730 { 731 const labelsTestCase& test_case = test_cases[test_case_index]; 732 733 const GLenum identifier = test_case.m_identifier; 734 const GLuint id = test_case.m_create(m_gl, m_rc); 735 736 try 737 { 738 GLchar buffer[bufSize] = "HelloWorld"; 739 GLsizei length; 740 741 /* 742 * - query label; It is expected that result will be an empty string and length 743 * will be zero; 744 */ 745 m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer); 746 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel"); 747 748 if (0 != length) 749 { 750 TCU_FAIL("Just created object has label of length != 0"); 751 } 752 753 if (0 != buffer[0]) 754 { 755 TCU_FAIL("Just created object has not empty label"); 756 } 757 758 /* 759 * - assign label to object; 760 * - query label; It is expected that result will be equal to the provided 761 * label and length will be correct; 762 */ 763 m_gl->objectLabel(identifier, id, -1 /* length */, label); 764 GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel"); 765 766 m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer); 767 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel"); 768 769 if (label_length != length) 770 { 771 TCU_FAIL("Length is different than length of set label"); 772 } 773 774 if (0 != strcmp(buffer, label)) 775 { 776 TCU_FAIL("Different label returned"); 777 } 778 779 /* 780 * - query length only; Correct value is expected; 781 */ 782 length = 0; 783 784 m_gl->getObjectLabel(identifier, id, 0 /* bufSize */, &length, 0 /* label */); 785 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel"); 786 787 if (label_length != length) 788 { 789 TCU_FAIL("Invalid length returned when label and bufSize are set to 0"); 790 } 791 792 /* 793 * - query label with <bufSize> less than actual length of label; It is 794 * expected that only <bufSize> characters will be stored in buffer (including 795 * NULL); 796 */ 797 length = 0; 798 strcpy(buffer, "HelloWorld"); 799 800 m_gl->getObjectLabel(identifier, id, 2 /* bufSize */, &length, buffer); 801 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel"); 802 803 if (buffer[0] != label[0]) 804 { 805 TCU_FAIL("Different label returned"); 806 } 807 808 if (buffer[1] != 0) 809 { 810 TCU_FAIL("GetObjectLabel did not stored NULL at the end of string"); 811 } 812 813 if (buffer[2] != 'l') 814 { 815 TCU_FAIL("GetObjectLabel overflowed buffer"); 816 } 817 818 /* 819 * - query label with <bufSize> equal zero; It is expected that buffer contents 820 * will not be modified; 821 */ 822 length = 0; 823 strcpy(buffer, "HelloWorld"); 824 825 m_gl->getObjectLabel(identifier, id, 0 /* bufSize */, &length, buffer); 826 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel"); 827 828 if (0 != strcmp(buffer, "HelloWorld")) 829 { 830 TCU_FAIL("GetObjectLabel modified buffer, bufSize set to 0"); 831 } 832 833 /* 834 * - assign empty string as label to object; 835 * - query label, it is expected that result will be an empty string and length 836 * will be zero; 837 */ 838 m_gl->objectLabel(identifier, id, -1 /* length */, ""); 839 GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel"); 840 841 m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer); 842 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel"); 843 844 if (0 != length) 845 { 846 TCU_FAIL("Label length is != 0, empty string was set"); 847 } 848 849 if (0 != buffer[0]) 850 { 851 TCU_FAIL("Non empty label returned, empty string was set"); 852 } 853 854 /* 855 * - assign NULL as label to object; 856 * - query label, it is expected that result will be an empty string and length 857 * will be zero; 858 */ 859 m_gl->objectLabel(identifier, id, 2, 0 /* label */); 860 GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel"); 861 862 m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer); 863 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel"); 864 865 if (0 != length) 866 { 867 TCU_FAIL("Label length is != 0, label was removed"); 868 } 869 870 if (0 != buffer[0]) 871 { 872 TCU_FAIL("Different label returned, label was removed"); 873 } 874 } 875 catch (const std::exception& exc) 876 { 877 test_case.m_destroy(m_gl, id); 878 879 m_context.getTestContext().getLog() 880 << tcu::TestLog::Message << "Error during test case: " << test_case.m_name << tcu::TestLog::EndMessage; 881 882 TCU_FAIL(exc.what()); 883 } 884 885 test_case.m_destroy(m_gl, id); 886 } 887 888 /* Set result */ 889 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 890 891 /* Done */ 892 TestBase::done(); 893 894 return tcu::TestNode::STOP; 895 } 896 897 /** Create buffer 898 * 899 * @param gl GL functions 900 * 901 * @return ID of created resource 902 **/ 903 GLuint LabelsTest::createBuffer(const Functions* gl, const glu::RenderContext* rc) 904 { 905 GLuint id = 0; 906 907 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 908 { 909 gl->createBuffers(1, &id); 910 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateBuffers"); 911 } 912 else 913 { 914 gl->genBuffers(1, &id); 915 gl->bindBuffer(GL_ARRAY_BUFFER, id); 916 GLU_EXPECT_NO_ERROR(gl->getError(), "GenBuffers"); 917 } 918 919 return id; 920 } 921 922 /** Create FBO 923 * 924 * @param gl GL functions 925 * 926 * @return ID of created resource 927 **/ 928 GLuint LabelsTest::createFramebuffer(const Functions* gl, const glu::RenderContext* rc) 929 { 930 GLuint id = 0; 931 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 932 { 933 gl->createFramebuffers(1, &id); 934 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateFramebuffers"); 935 } 936 else 937 { 938 GLint currentFbo; 939 gl->getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤tFbo); 940 gl->genFramebuffers(1, &id); 941 gl->bindFramebuffer(GL_DRAW_FRAMEBUFFER, id); 942 gl->bindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFbo); 943 GLU_EXPECT_NO_ERROR(gl->getError(), "GenFramebuffers / BindFramebuffer"); 944 } 945 946 return id; 947 } 948 949 /** Create program 950 * 951 * @param gl GL functions 952 * 953 * @return ID of created resource 954 **/ 955 GLuint LabelsTest::createProgram(const Functions* gl, const glu::RenderContext*) 956 { 957 GLuint id = gl->createProgram(); 958 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateProgram"); 959 960 return id; 961 } 962 963 /** Create pipeline 964 * 965 * @param gl GL functions 966 * 967 * @return ID of created resource 968 **/ 969 GLuint LabelsTest::createProgramPipeline(const Functions* gl, const glu::RenderContext* rc) 970 { 971 GLuint id = 0; 972 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 973 { 974 gl->createProgramPipelines(1, &id); 975 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateProgramPipelines"); 976 } 977 else 978 { 979 gl->genProgramPipelines(1, &id); 980 gl->bindProgramPipeline(id); 981 GLU_EXPECT_NO_ERROR(gl->getError(), "GenProgramPipelines / BindProgramPipeline"); 982 } 983 984 return id; 985 } 986 987 /** Create query 988 * 989 * @param gl GL functions 990 * 991 * @return ID of created resource 992 **/ 993 GLuint LabelsTest::createQuery(const Functions* gl, const glu::RenderContext* rc) 994 { 995 GLuint id = 0; 996 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 997 { 998 gl->createQueries(GL_TIMESTAMP, 1, &id); 999 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateQueries"); 1000 } 1001 else 1002 { 1003 gl->genQueries(1, &id); 1004 gl->beginQuery(GL_SAMPLES_PASSED, id); 1005 gl->endQuery(GL_SAMPLES_PASSED); 1006 GLU_EXPECT_NO_ERROR(gl->getError(), "GenQueries / BeginQuery / EndQuery"); 1007 } 1008 1009 return id; 1010 } 1011 1012 /** Create render buffer 1013 * 1014 * @param gl GL functions 1015 * 1016 * @return ID of created resource 1017 **/ 1018 GLuint LabelsTest::createRenderbuffer(const Functions* gl, const glu::RenderContext* rc) 1019 { 1020 GLuint id = 0; 1021 1022 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 1023 { 1024 gl->createRenderbuffers(1, &id); 1025 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateRenderbuffers"); 1026 } 1027 else 1028 { 1029 gl->genRenderbuffers(1, &id); 1030 gl->bindRenderbuffer(GL_RENDERBUFFER, id); 1031 gl->bindRenderbuffer(GL_RENDERBUFFER, 0); 1032 GLU_EXPECT_NO_ERROR(gl->getError(), "GenRenderbuffers / BindRenderbuffer"); 1033 } 1034 1035 return id; 1036 } 1037 1038 /** Create sampler 1039 * 1040 * @param gl GL functions 1041 * 1042 * @return ID of created resource 1043 **/ 1044 GLuint LabelsTest::createSampler(const Functions* gl, const glu::RenderContext* rc) 1045 { 1046 GLuint id = 0; 1047 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 1048 { 1049 gl->createSamplers(1, &id); 1050 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateSamplers"); 1051 } 1052 else 1053 { 1054 gl->genSamplers(1, &id); 1055 gl->bindSampler(0, id); 1056 gl->bindSampler(0, 0); 1057 GLU_EXPECT_NO_ERROR(gl->getError(), "GenSamplers / BindSampler"); 1058 } 1059 1060 return id; 1061 } 1062 1063 /** Create shader 1064 * 1065 * @param gl GL functions 1066 * 1067 * @return ID of created resource 1068 **/ 1069 GLuint LabelsTest::createShader(const Functions* gl, const glu::RenderContext*) 1070 { 1071 GLuint id = gl->createShader(GL_VERTEX_SHADER); 1072 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateShader"); 1073 1074 return id; 1075 } 1076 1077 /** Create texture 1078 * 1079 * @param gl GL functions 1080 * 1081 * @return ID of created resource 1082 **/ 1083 GLuint LabelsTest::createTexture(const Functions* gl, const glu::RenderContext* rc) 1084 { 1085 GLuint id = 0; 1086 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 1087 { 1088 gl->createTextures(GL_TEXTURE_2D, 1, &id); 1089 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateTextures"); 1090 } 1091 else 1092 { 1093 gl->genTextures(1, &id); 1094 gl->bindTexture(GL_TEXTURE_2D, id); 1095 gl->bindTexture(GL_TEXTURE_2D, 0); 1096 GLU_EXPECT_NO_ERROR(gl->getError(), "GenTextures / BindTexture"); 1097 } 1098 1099 return id; 1100 } 1101 1102 /** Create XFB 1103 * 1104 * @param gl GL functions 1105 * 1106 * @return ID of created resource 1107 **/ 1108 GLuint LabelsTest::createTransformFeedback(const Functions* gl, const glu::RenderContext* rc) 1109 { 1110 GLuint id = 0; 1111 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 1112 { 1113 gl->createTransformFeedbacks(1, &id); 1114 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateTransformFeedbacks"); 1115 } 1116 else 1117 { 1118 gl->genTransformFeedbacks(1, &id); 1119 gl->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, id); 1120 gl->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); 1121 GLU_EXPECT_NO_ERROR(gl->getError(), "GenTransformFeedbacks / BindTransformFeedback"); 1122 } 1123 1124 return id; 1125 } 1126 1127 /** Create VAO 1128 * 1129 * @param gl GL functions 1130 * 1131 * @return ID of created resource 1132 **/ 1133 GLuint LabelsTest::createVertexArray(const Functions* gl, const glu::RenderContext* rc) 1134 { 1135 GLuint id = 0; 1136 1137 if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5))) 1138 { 1139 gl->createVertexArrays(1, &id); 1140 GLU_EXPECT_NO_ERROR(gl->getError(), "CreateVertexArrays"); 1141 } 1142 else 1143 { 1144 gl->genVertexArrays(1, &id); 1145 gl->bindVertexArray(id); 1146 gl->bindVertexArray(0); 1147 GLU_EXPECT_NO_ERROR(gl->getError(), "GenVertexArrays / BindVertexArrays"); 1148 } 1149 1150 return id; 1151 } 1152 1153 /** Destroy buffer 1154 * 1155 * @param gl GL functions 1156 * @param id ID of resource 1157 **/ 1158 GLvoid LabelsTest::deleteBuffer(const Functions* gl, GLuint id) 1159 { 1160 gl->deleteBuffers(1, &id); 1161 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteBuffers"); 1162 } 1163 1164 /** Destroy FBO 1165 * 1166 * @param gl GL functions 1167 * @param id ID of resource 1168 **/ 1169 GLvoid LabelsTest::deleteFramebuffer(const Functions* gl, GLuint id) 1170 { 1171 gl->deleteFramebuffers(1, &id); 1172 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteFramebuffers"); 1173 } 1174 1175 /** Destroy program 1176 * 1177 * @param gl GL functions 1178 * @param id ID of resource 1179 **/ 1180 GLvoid LabelsTest::deleteProgram(const Functions* gl, GLuint id) 1181 { 1182 gl->deleteProgram(id); 1183 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteProgram"); 1184 } 1185 1186 /** Destroy pipeline 1187 * 1188 * @param gl GL functions 1189 * @param id ID of resource 1190 **/ 1191 GLvoid LabelsTest::deleteProgramPipeline(const Functions* gl, GLuint id) 1192 { 1193 gl->deleteProgramPipelines(1, &id); 1194 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteProgramPipelines"); 1195 } 1196 1197 /** Destroy query 1198 * 1199 * @param gl GL functions 1200 * @param id ID of resource 1201 **/ 1202 GLvoid LabelsTest::deleteQuery(const Functions* gl, GLuint id) 1203 { 1204 gl->deleteQueries(1, &id); 1205 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteQueries"); 1206 } 1207 1208 /** Destroy render buffer 1209 * 1210 * @param gl GL functions 1211 * @param id ID of resource 1212 **/ 1213 GLvoid LabelsTest::deleteRenderbuffer(const Functions* gl, GLuint id) 1214 { 1215 gl->deleteRenderbuffers(1, &id); 1216 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteRenderbuffers"); 1217 } 1218 1219 /** Destroy sampler 1220 * 1221 * @param gl GL functions 1222 * @param id ID of resource 1223 **/ 1224 GLvoid LabelsTest::deleteSampler(const Functions* gl, GLuint id) 1225 { 1226 gl->deleteSamplers(1, &id); 1227 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteSamplers"); 1228 } 1229 1230 /** Destroy shader 1231 * 1232 * @param gl GL functions 1233 * @param id ID of resource 1234 **/ 1235 GLvoid LabelsTest::deleteShader(const Functions* gl, GLuint id) 1236 { 1237 gl->deleteShader(id); 1238 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteShader"); 1239 } 1240 1241 /** Destroy texture 1242 * 1243 * @param gl GL functions 1244 * @param id ID of resource 1245 **/ 1246 GLvoid LabelsTest::deleteTexture(const Functions* gl, GLuint id) 1247 { 1248 gl->deleteTextures(1, &id); 1249 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteTextures"); 1250 } 1251 1252 /** Destroy XFB 1253 * 1254 * @param gl GL functions 1255 * @param id ID of resource 1256 **/ 1257 GLvoid LabelsTest::deleteTransformFeedback(const Functions* gl, GLuint id) 1258 { 1259 gl->deleteTransformFeedbacks(1, &id); 1260 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteTransformFeedbacks"); 1261 } 1262 1263 /** Destroy VAO 1264 * 1265 * @param gl GL functions 1266 * @param id ID of resource 1267 **/ 1268 GLvoid LabelsTest::deleteVertexArray(const Functions* gl, GLuint id) 1269 { 1270 gl->deleteVertexArrays(1, &id); 1271 GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteVertexArrays"); 1272 } 1273 1274 /** Constructor 1275 * 1276 * @param context Test context 1277 * @param is_debug Selects if debug or non-debug context should be used 1278 * @param name Name of test 1279 **/ 1280 ReceiveingMessagesTest::ReceiveingMessagesTest(deqp::Context& context) 1281 : TestCase(context, "receiveing_messages", "Verifies that messages can be received") 1282 , TestBase(context, true /* is_debug */) 1283 { 1284 /* Nothing to be done */ 1285 } 1286 1287 /** Execute test 1288 * 1289 * @return tcu::TestNode::STOP 1290 **/ 1291 tcu::TestNode::IterateResult ReceiveingMessagesTest::iterate() 1292 { 1293 static const size_t bufSize = 32; 1294 static const GLchar label[] = "foo"; 1295 static const size_t label_length = sizeof(label) / sizeof(label[0]) - 1; 1296 static const size_t read_messages = 4; 1297 1298 GLuint callback_counter = 0; 1299 GLint max_debug_messages = 0; 1300 1301 /* Initialize render context */ 1302 TestBase::init(); 1303 1304 /* Get max number of debug messages */ 1305 m_gl->getIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES, &max_debug_messages); 1306 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 1307 1308 /* 1309 * - verify that the state of DEBUG_OUTPUT is enabled as it should be by 1310 * default; 1311 * - verify that state of DEBUG_CALLBACK_FUNCTION and 1312 * DEBUG_CALLBACK_USER_PARAM are NULL; 1313 */ 1314 { 1315 inspectDebugState(GL_TRUE, 0 /* cb */, 0 /* info */); 1316 } 1317 1318 /* 1319 * Ignore spurious performance messages 1320 */ 1321 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_PERFORMANCE /* type */, 1322 GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */); 1323 1324 /* 1325 * - insert a message with DebugMessageInsert; 1326 * - inspect message log to check if the message is reported; 1327 * - inspect message log again, there should be no messages; 1328 */ 1329 { 1330 GLchar messageLog[bufSize]; 1331 GLenum sources[read_messages]; 1332 GLenum types[read_messages]; 1333 GLuint ids[read_messages]; 1334 GLenum severities[read_messages]; 1335 GLsizei lengths[read_messages]; 1336 1337 cleanMessageLog(m_gl); 1338 1339 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1340 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1341 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1342 1343 GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, sources /* sources */, 1344 types /* types */, ids /* ids */, severities /* severities */, 1345 lengths /* lengths */, messageLog /* messageLog */); 1346 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog"); 1347 1348 if (1 != ret) 1349 { 1350 m_context.getTestContext().getLog() << tcu::TestLog::Message 1351 << "GetDebugMessageLog returned invalid number of messages: " << ret 1352 << ", expected 1" << tcu::TestLog::EndMessage; 1353 1354 TCU_FAIL("Invalid value returned by GetDebugMessageLog"); 1355 } 1356 1357 if (GL_DEBUG_SOURCE_APPLICATION != sources[0]) 1358 { 1359 TCU_FAIL("Invalid source value returned by GetDebugMessageLog"); 1360 } 1361 1362 if (GL_DEBUG_TYPE_ERROR != types[0]) 1363 { 1364 TCU_FAIL("Invalid type value returned by GetDebugMessageLog"); 1365 } 1366 1367 if (11 != ids[0]) 1368 { 1369 TCU_FAIL("Invalid id value returned by GetDebugMessageLog"); 1370 } 1371 1372 if (GL_DEBUG_SEVERITY_HIGH != severities[0]) 1373 { 1374 TCU_FAIL("Invalid severity value returned by GetDebugMessageLog"); 1375 } 1376 1377 // DebugMessageInsert's length does not include null-terminated character (if length is positive) 1378 // But GetDebugMessageLog's length include null-terminated character 1379 // OpenGL 4.5 Core Spec, Page 530 and Page 535 1380 if (label_length + 1 != lengths[0]) 1381 { 1382 TCU_FAIL("Invalid length value returned by GetDebugMessageLog"); 1383 } 1384 1385 if (0 != strcmp(label, messageLog)) 1386 { 1387 TCU_FAIL("Invalid message returned by GetDebugMessageLog"); 1388 } 1389 } 1390 1391 /* 1392 * - disable DEBUG_OUTPUT; 1393 * - insert a message with DebugMessageInsert; 1394 * - inspect message log again, there should be no messages; 1395 */ 1396 { 1397 m_gl->disable(GL_DEBUG_OUTPUT); 1398 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Disable"); 1399 1400 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1401 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1402 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1403 1404 inspectMessageLog(0); 1405 } 1406 1407 /* 1408 * - enable DEBUG_OUTPUT; 1409 * - register debug message callback with DebugMessageCallback; 1410 * - verify that the state of DEBUG_CALLBACK_FUNCTION and 1411 * DEBUG_CALLBACK_USER_PARAM are correct; 1412 * - insert a message with DebugMessageInsert; 1413 * - it is expected that debug message callback will be executed for 1414 * the message; 1415 * - inspect message log to check there are no messages; 1416 */ 1417 { 1418 m_gl->enable(GL_DEBUG_OUTPUT); 1419 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable"); 1420 1421 m_gl->debugMessageCallback(debug_proc, &callback_counter); 1422 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageCallback"); 1423 1424 inspectDebugState(GL_TRUE, debug_proc, &callback_counter); 1425 1426 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1427 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1428 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1429 1430 inspectCallbackCounter(callback_counter, 1); 1431 1432 inspectMessageLog(0); 1433 } 1434 1435 /* 1436 * - disable DEBUG_OUTPUT; 1437 * - insert a message with DebugMessageInsert; 1438 * - debug message callback should not be called; 1439 * - inspect message log to check there are no messages; 1440 */ 1441 { 1442 m_gl->disable(GL_DEBUG_OUTPUT); 1443 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Disable"); 1444 1445 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1446 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1447 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1448 1449 inspectCallbackCounter(callback_counter, 1); 1450 1451 inspectMessageLog(0); 1452 } 1453 1454 /* 1455 * - enable DEBUG_OUTPUT; 1456 * - execute DebugMessageControl with <type> DEBUG_TYPE_ERROR, <severity> 1457 * DEBUG_SEVERITY_HIGH and <enabled> FALSE; 1458 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR 1459 * and <severity> DEBUG_SEVERITY_MEDIUM; 1460 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER 1461 * and <severity> DEBUG_SEVERITY_HIGH; 1462 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER 1463 * and <severity> DEBUG_SEVERITY_LOW; 1464 * - debug message callback should not be called; 1465 * - inspect message log to check there are no messages; 1466 */ 1467 { 1468 m_gl->enable(GL_DEBUG_OUTPUT); 1469 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable"); 1470 1471 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */, 1472 GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */); 1473 1474 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DONT_CARE /* type */, 1475 GL_DEBUG_SEVERITY_HIGH /* severity */, 0 /* counts */, 0 /* ids */, 1476 GL_FALSE /* enabled */); 1477 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl"); 1478 1479 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1480 GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */, label); 1481 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1482 1483 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 1484 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1485 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1486 1487 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 1488 GL_DEBUG_SEVERITY_LOW /* severity */, label_length /* length */, label); 1489 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1490 1491 inspectCallbackCounter(callback_counter, 1); 1492 1493 inspectMessageLog(0); 1494 } 1495 1496 /* 1497 * - set NULL as debug message callback; 1498 * - verify that state of DEBUG_CALLBACK_FUNCTION and 1499 * DEBUG_CALLBACK_USER_PARAM are NULL; 1500 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR 1501 * and <severity> DEBUG_SEVERITY_MEDIUM; 1502 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER 1503 * and <severity> DEBUG_SEVERITY_HIGH; 1504 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER 1505 * and <severity> DEBUG_SEVERITY_LOW; 1506 * - inspect message log to check there are no messages; 1507 */ 1508 { 1509 m_gl->debugMessageCallback(0, 0); 1510 1511 inspectDebugState(GL_TRUE, 0, 0); 1512 1513 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1514 GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */, label); 1515 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1516 1517 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 1518 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1519 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1520 1521 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 1522 GL_DEBUG_SEVERITY_LOW /* severity */, label_length /* length */, label); 1523 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1524 1525 inspectMessageLog(0); 1526 } 1527 1528 /* 1529 * - execute DebugMessageControl to enable messages of <type> DEBUG_TYPE_ERROR 1530 * and <severity> DEBUG_SEVERITY_HIGH. 1531 */ 1532 { 1533 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */, 1534 GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_TRUE /* enabled */); 1535 1536 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DONT_CARE /* type */, 1537 GL_DEBUG_SEVERITY_HIGH /* severity */, 0 /* counts */, 0 /* ids */, 1538 GL_TRUE /* enabled */); 1539 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl"); 1540 } 1541 1542 /* 1543 * - insert MAX_DEBUG_LOGGED_MESSAGES + 1 unique messages with 1544 * DebugMessageInsert; 1545 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that 1546 * MAX_DEBUG_LOGGED_MESSAGES will be reported; 1547 */ 1548 { 1549 for (GLint i = 0; i < max_debug_messages + 1; ++i) 1550 { 1551 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 1552 i /* id */, GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */, 1553 label); 1554 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1555 } 1556 1557 GLint n_debug_messages = 0; 1558 1559 m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages); 1560 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 1561 1562 if (n_debug_messages != max_debug_messages) 1563 { 1564 m_context.getTestContext().getLog() 1565 << tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected " 1566 << max_debug_messages << tcu::TestLog::EndMessage; 1567 1568 TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES"); 1569 } 1570 } 1571 1572 /* 1573 * If MAX_DEBUG_LOGGED_MESSAGES is greater than 1: 1574 * - inspect first half of the message log by specifying proper <count>; Verify 1575 * that messages are reported in order from the oldest to the newest; Check 1576 * that <count> messages were stored into provided buffers; 1577 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that <count> messages 1578 * were removed from log; 1579 * - inspect rest of the message log with <bufSize> too small to held last 1580 * message; Verify that messages are reported in order from the oldest to the 1581 * newest; Verify that maximum <bufSize> characters were written to 1582 * <messageLog>; 1583 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that one message is 1584 * available; 1585 * - fetch the message and verify it is the newest one; 1586 */ 1587 if (1 != max_debug_messages) 1588 { 1589 GLint half_count = max_debug_messages / 2; 1590 GLint n_debug_messages = 0; 1591 GLint rest_count = max_debug_messages - half_count; 1592 1593 GLsizei buf_size = (GLsizei)((half_count + 1) * (label_length + 1)); 1594 1595 std::vector<GLchar> messageLog; 1596 std::vector<GLenum> sources; 1597 std::vector<GLenum> types; 1598 std::vector<GLuint> ids; 1599 std::vector<GLenum> severities; 1600 std::vector<GLsizei> lengths; 1601 1602 messageLog.resize(buf_size); 1603 sources.resize(half_count + 1); 1604 types.resize(half_count + 1); 1605 ids.resize(half_count + 1); 1606 severities.resize(half_count + 1); 1607 lengths.resize(half_count + 1); 1608 1609 GLuint ret = m_gl->getDebugMessageLog(half_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */, 1610 &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */, 1611 &lengths[0] /* lengths */, &messageLog[0] /* messageLog */); 1612 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog"); 1613 1614 if (ret != (GLuint)half_count) 1615 { 1616 m_context.getTestContext().getLog() << tcu::TestLog::Message 1617 << "GetDebugMessageLog returned unexpected number of messages: " << ret 1618 << ", expected " << half_count << tcu::TestLog::EndMessage; 1619 1620 TCU_FAIL("Invalid number of meessages"); 1621 } 1622 1623 m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages); 1624 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 1625 1626 if (n_debug_messages != rest_count) 1627 { 1628 m_context.getTestContext().getLog() 1629 << tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected " 1630 << rest_count << tcu::TestLog::EndMessage; 1631 1632 TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES"); 1633 } 1634 1635 for (GLint i = 0; i < half_count; ++i) 1636 { 1637 if (GL_DEBUG_SOURCE_APPLICATION != sources[i]) 1638 { 1639 TCU_FAIL("Invalid source value returned by GetDebugMessageLog"); 1640 } 1641 1642 if (GL_DEBUG_TYPE_ERROR != types[i]) 1643 { 1644 TCU_FAIL("Invalid type value returned by GetDebugMessageLog"); 1645 } 1646 1647 if ((GLuint)i != ids[i]) 1648 { 1649 TCU_FAIL("Invalid id value returned by GetDebugMessageLog"); 1650 } 1651 1652 if (GL_DEBUG_SEVERITY_MEDIUM != severities[i]) 1653 { 1654 TCU_FAIL("Invalid severity value returned by GetDebugMessageLog"); 1655 } 1656 1657 // DebugMessageInsert's length does not include null-terminated character (if length is positive) 1658 // But GetDebugMessageLog's length include null-terminated character 1659 // OpenGL 4.5 Core Spec, Page 530 and Page 535 1660 if (label_length + 1 != lengths[i]) 1661 { 1662 TCU_FAIL("Invalid length value returned by GetDebugMessageLog"); 1663 } 1664 1665 if (0 != strcmp(label, &messageLog[i * (label_length + 1)])) 1666 { 1667 TCU_FAIL("Invalid message returned by GetDebugMessageLog"); 1668 } 1669 } 1670 1671 /* */ 1672 buf_size = (GLsizei)((rest_count - 1) * (label_length + 1) + label_length); 1673 memset(&messageLog[0], 0, messageLog.size()); 1674 1675 ret = m_gl->getDebugMessageLog(rest_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */, 1676 &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */, 1677 &lengths[0] /* lengths */, &messageLog[0] /* messageLog */); 1678 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog"); 1679 1680 if (ret != (GLuint)(rest_count - 1)) 1681 { 1682 m_context.getTestContext().getLog() << tcu::TestLog::Message 1683 << "GetDebugMessageLog returned unexpected number of messages: " << ret 1684 << ", expected " << (rest_count - 1) << tcu::TestLog::EndMessage; 1685 1686 TCU_FAIL("Invalid number of meessages"); 1687 } 1688 1689 m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages); 1690 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 1691 1692 if (n_debug_messages != 1) 1693 { 1694 m_context.getTestContext().getLog() 1695 << tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected " 1696 << (rest_count - 1) << tcu::TestLog::EndMessage; 1697 1698 TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES"); 1699 } 1700 1701 for (GLint i = 0; i < (rest_count - 1); ++i) 1702 { 1703 if (GL_DEBUG_SOURCE_APPLICATION != sources[i]) 1704 { 1705 TCU_FAIL("Invalid source value returned by GetDebugMessageLog"); 1706 } 1707 1708 if (GL_DEBUG_TYPE_ERROR != types[i]) 1709 { 1710 TCU_FAIL("Invalid type value returned by GetDebugMessageLog"); 1711 } 1712 1713 if ((GLuint)(i + half_count) != ids[i]) 1714 { 1715 TCU_FAIL("Invalid id value returned by GetDebugMessageLog"); 1716 } 1717 1718 if (GL_DEBUG_SEVERITY_MEDIUM != severities[i]) 1719 { 1720 TCU_FAIL("Invalid severity value returned by GetDebugMessageLog"); 1721 } 1722 1723 // DebugMessageInsert's length does not include null-terminated character (if length is positive) 1724 // But GetDebugMessageLog's length include null-terminated character 1725 // OpenGL 4.5 Core Spec, Page 530 and Page 535 1726 if (label_length + 1 != lengths[i]) 1727 { 1728 TCU_FAIL("Invalid length value returned by GetDebugMessageLog"); 1729 } 1730 1731 if (0 != strcmp(label, &messageLog[i * (label_length + 1)])) 1732 { 1733 TCU_FAIL("Invalid message returned by GetDebugMessageLog"); 1734 } 1735 } 1736 1737 /* */ 1738 memset(&messageLog[0], 0, messageLog.size()); 1739 1740 ret = m_gl->getDebugMessageLog(rest_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */, 1741 &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */, 1742 &lengths[0] /* lengths */, &messageLog[0] /* messageLog */); 1743 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog"); 1744 1745 if (ret != 1) 1746 { 1747 m_context.getTestContext().getLog() << tcu::TestLog::Message 1748 << "GetDebugMessageLog returned unexpected number of messages: " << ret 1749 << ", expected 1" << tcu::TestLog::EndMessage; 1750 1751 TCU_FAIL("Invalid number of meessages"); 1752 } 1753 1754 m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages); 1755 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 1756 1757 if (n_debug_messages != 0) 1758 { 1759 m_context.getTestContext().getLog() 1760 << tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected 1" 1761 << tcu::TestLog::EndMessage; 1762 1763 TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES"); 1764 } 1765 1766 if (GL_DEBUG_SOURCE_APPLICATION != sources[0]) 1767 { 1768 TCU_FAIL("Invalid source value returned by GetDebugMessageLog"); 1769 } 1770 1771 if (GL_DEBUG_TYPE_ERROR != types[0]) 1772 { 1773 TCU_FAIL("Invalid type value returned by GetDebugMessageLog"); 1774 } 1775 1776 if ((GLuint)(max_debug_messages - 1) != ids[0]) 1777 { 1778 TCU_FAIL("Invalid id value returned by GetDebugMessageLog"); 1779 } 1780 1781 if (GL_DEBUG_SEVERITY_MEDIUM != severities[0]) 1782 { 1783 TCU_FAIL("Invalid severity value returned by GetDebugMessageLog"); 1784 } 1785 1786 // DebugMessageInsert's length does not include null-terminated character (if length is positive) 1787 // But GetDebugMessageLog's length include null-terminated character 1788 // OpenGL 4.5 Core Spec, Page 530 and Page 535 1789 if (label_length + 1 != lengths[0]) 1790 { 1791 TCU_FAIL("Invalid length value returned by GetDebugMessageLog"); 1792 } 1793 1794 if (0 != strcmp(label, &messageLog[0])) 1795 { 1796 TCU_FAIL("Invalid message returned by GetDebugMessageLog"); 1797 } 1798 } 1799 1800 /* Set result */ 1801 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1802 1803 /* Done */ 1804 TestBase::done(); 1805 1806 return tcu::TestNode::STOP; 1807 } 1808 1809 /** Debug callback used by the test, increase counter by one 1810 * 1811 * @param ignored 1812 * @param ignored 1813 * @param ignored 1814 * @param ignored 1815 * @param ignored 1816 * @param ignored 1817 * @param info Pointer to uint counter 1818 **/ 1819 void ReceiveingMessagesTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */, 1820 glw::GLenum /* severity */, glw::GLsizei /* length */, 1821 const glw::GLchar* /* message */, const void* info) 1822 { 1823 GLuint* counter = (GLuint*)info; 1824 1825 *counter += 1; 1826 } 1827 1828 /** Inspects state of DEBUG_OUTPUT and debug callback 1829 * 1830 * @param expected_state Expected state of DEBUG_OUTPUT 1831 * @param expected_callback Expected state of DEBUG_CALLBACK_FUNCTION 1832 * @param expected_user_info Expected state of DEBUG_CALLBACK_USER_PARAM 1833 **/ 1834 void ReceiveingMessagesTest::inspectDebugState(GLboolean expected_state, GLDEBUGPROC expected_callback, 1835 GLvoid* expected_user_info) const 1836 { 1837 GLboolean debug_state = -1; 1838 m_gl->getBooleanv(GL_DEBUG_OUTPUT, &debug_state); 1839 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetBooleanv"); 1840 1841 if (expected_state != debug_state) 1842 { 1843 m_context.getTestContext().getLog() << tcu::TestLog::Message << "State of DEBUG_OUTPUT: " << debug_state 1844 << ", expected " << expected_state << tcu::TestLog::EndMessage; 1845 1846 TCU_FAIL("Invalid state of DEBUG_OUTPUT"); 1847 } 1848 1849 GLvoid* callback_procedure = 0; 1850 m_gl->getPointerv(GL_DEBUG_CALLBACK_FUNCTION, &callback_procedure); 1851 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetPointerv"); 1852 1853 if (expected_callback != callback_procedure) 1854 { 1855 TCU_FAIL("Invalid state of DEBUG_CALLBACK_FUNCTION"); 1856 } 1857 1858 GLvoid* callback_user_info = 0; 1859 m_gl->getPointerv(GL_DEBUG_CALLBACK_USER_PARAM, &callback_user_info); 1860 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetPointerv"); 1861 1862 if (expected_user_info != callback_user_info) 1863 { 1864 TCU_FAIL("Invalid state of DEBUG_CALLBACK_USER_PARAM"); 1865 } 1866 } 1867 1868 /** Inspects value of counter used by callback 1869 * 1870 * @param callback_counter Reference to counter 1871 * @param expected_number_of_messages Expected value of counter 1872 **/ 1873 void ReceiveingMessagesTest::inspectCallbackCounter(GLuint& callback_counter, GLuint expected_number_of_messages) const 1874 { 1875 m_gl->finish(); 1876 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish"); 1877 1878 if (expected_number_of_messages != callback_counter) 1879 { 1880 m_context.getTestContext().getLog() 1881 << tcu::TestLog::Message << "Debug callback was executed invalid number of times: " << callback_counter 1882 << ", expected " << expected_number_of_messages << tcu::TestLog::EndMessage; 1883 1884 TCU_FAIL("Invalid execution of debug callback"); 1885 } 1886 } 1887 1888 /** Inspects amount of messages stored in log 1889 * 1890 * @param expected_number_of_messages Expected number of messages 1891 **/ 1892 void ReceiveingMessagesTest::inspectMessageLog(GLuint expected_number_of_messages) const 1893 { 1894 static const size_t bufSize = 32; 1895 static const size_t read_messages = 4; 1896 1897 GLchar messageLog[bufSize]; 1898 GLenum sources[read_messages]; 1899 GLenum types[read_messages]; 1900 GLuint ids[read_messages]; 1901 GLenum severities[read_messages]; 1902 GLsizei lengths[read_messages]; 1903 1904 GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, sources /* sources */, 1905 types /* types */, ids /* ids */, severities /* severities */, 1906 lengths /* lengths */, messageLog /* messageLog */); 1907 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog"); 1908 1909 if (expected_number_of_messages != ret) 1910 { 1911 m_context.getTestContext().getLog() << tcu::TestLog::Message 1912 << "GetDebugMessageLog returned invalid number of messages: " << ret 1913 << ", expected " << expected_number_of_messages << tcu::TestLog::EndMessage; 1914 1915 TCU_FAIL("Invalid value returned by GetDebugMessageLog"); 1916 } 1917 } 1918 1919 /** Constructor 1920 * 1921 * @param context Test context 1922 * @param is_debug Selects if debug or non-debug context should be used 1923 * @param name Name of test 1924 **/ 1925 GroupsTest::GroupsTest(deqp::Context& context) 1926 : TestCase(context, "groups", "Verifies that groups can be used to control generated messages") 1927 , TestBase(context, true /* is_debug */) 1928 { 1929 /* Nothing to be done */ 1930 } 1931 1932 /** Execute test 1933 * 1934 * @return tcu::TestNode::STOP 1935 **/ 1936 tcu::TestNode::IterateResult GroupsTest::iterate() 1937 { 1938 static const GLchar label[] = "foo"; 1939 static const size_t label_length = sizeof(label) / sizeof(label[0]) - 1; 1940 1941 /* Initialize render context */ 1942 TestBase::init(); 1943 1944 cleanMessageLog(m_gl); 1945 1946 /* 1947 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1; 1948 */ 1949 inspectGroupStack(1); 1950 1951 /* 1952 * - insert message with <type> DEBUG_TYPE_ERROR; 1953 * - inspect message log to check if the message is reported; 1954 * - insert message with <type> DEBUG_TYPE_OTHER; 1955 * - inspect message log to check if the message is reported; 1956 */ 1957 { 1958 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1959 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1960 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1961 1962 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1963 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1964 1965 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 1966 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1967 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1968 1969 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 1970 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1971 } 1972 1973 /* 1974 * - push debug group with unique <id> and <message>; 1975 * - inspect message log to check if the message about push is reported; 1976 * - disable messages with <type> DEBUG_TYPE_ERROR; 1977 * - insert message with <type> DEBUG_TYPE_ERROR; 1978 * - inspect message log to check there are no messages; 1979 * - insert message with <type> DEBUG_TYPE_OTHER; 1980 * - inspect message log to check if the message is reported; 1981 */ 1982 { 1983 m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 0xabcd0123 /* id */, -1 /* length */, label); 1984 GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup"); 1985 1986 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_PUSH_GROUP /* type */, 1987 0xabcd0123 /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */, 1988 label); 1989 1990 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */, 1991 GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */); 1992 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl"); 1993 1994 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 1995 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 1996 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 1997 1998 verifyEmptyLog(); 1999 2000 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 2001 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2002 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2003 2004 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 2005 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2006 } 2007 2008 /* 2009 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2; 2010 */ 2011 inspectGroupStack(2); 2012 2013 /* 2014 * - push debug group with unique <id> and <message>; 2015 * - inspect message log to check if the message about push is reported; 2016 * - disable messages with <type> DEBUG_TYPE_OTHER; 2017 * - insert message with <type> DEBUG_TYPE_ERROR; 2018 * - inspect message log to check there are no messages; 2019 * - insert message with <type> DEBUG_TYPE_OTHER; 2020 * - inspect message log to check there are no messages; 2021 */ 2022 { 2023 m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 0x0123abcd /* id */, -1 /* length */, label); 2024 GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup"); 2025 2026 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_PUSH_GROUP /* type */, 2027 0x0123abcd /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */, 2028 label); 2029 2030 m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_OTHER /* type */, 2031 GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */); 2032 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl"); 2033 2034 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 2035 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2036 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2037 2038 verifyEmptyLog(); 2039 2040 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 2041 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2042 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2043 2044 verifyEmptyLog(); 2045 } 2046 2047 /* 2048 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 3; 2049 */ 2050 inspectGroupStack(3); 2051 2052 /* 2053 * - pop debug group; 2054 * - inspect message log to check if the message about pop is reported and 2055 * corresponds with the second push; 2056 * - insert message with <type> DEBUG_TYPE_ERROR; 2057 * - inspect message log to check there are no messages; 2058 * - insert message with <type> DEBUG_TYPE_OTHER; 2059 * - inspect message log to check if the message is reported; 2060 */ 2061 { 2062 m_gl->popDebugGroup(); 2063 GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup"); 2064 2065 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_POP_GROUP /* type */, 2066 0x0123abcd /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */, 2067 label); 2068 2069 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 2070 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2071 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2072 2073 verifyEmptyLog(); 2074 2075 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 2076 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2077 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2078 2079 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 2080 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2081 } 2082 2083 /* 2084 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2; 2085 */ 2086 inspectGroupStack(2); 2087 2088 /* 2089 * - pop debug group; 2090 * - inspect message log to check if the message about pop is reported and 2091 * corresponds with the first push; 2092 * - insert message with <type> DEBUG_TYPE_ERROR; 2093 * - inspect message log to check if the message is reported; 2094 * - insert message with <type> DEBUG_TYPE_OTHER; 2095 * - inspect message log to check if the message is reported; 2096 */ 2097 { 2098 m_gl->popDebugGroup(); 2099 GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup"); 2100 2101 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_POP_GROUP /* type */, 2102 0xabcd0123 /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */, 2103 label); 2104 2105 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 2106 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2107 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2108 2109 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 2110 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2111 2112 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 2113 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2114 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2115 2116 inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */, 2117 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label); 2118 } 2119 2120 /* 2121 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1; 2122 */ 2123 inspectGroupStack(1); 2124 2125 /* Set result */ 2126 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2127 2128 /* Done */ 2129 TestBase::done(); 2130 2131 return tcu::TestNode::STOP; 2132 } 2133 2134 /** Inspects amount of groups on stack 2135 * 2136 * @param expected_depth Expected number of groups 2137 **/ 2138 void GroupsTest::inspectGroupStack(GLuint expected_depth) const 2139 { 2140 GLint stack_depth = 0; 2141 2142 m_gl->getIntegerv(GL_DEBUG_GROUP_STACK_DEPTH, &stack_depth); 2143 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv"); 2144 2145 if (expected_depth != (GLuint)stack_depth) 2146 { 2147 m_context.getTestContext().getLog() << tcu::TestLog::Message 2148 << "State of DEBUG_GROUP_STACK_DEPTH: " << stack_depth << ", expected " 2149 << expected_depth << tcu::TestLog::EndMessage; 2150 2151 TCU_FAIL("Invalid state of DEBUG_GROUP_STACK_DEPTH"); 2152 } 2153 } 2154 2155 /** Inspects first message stored in log 2156 * 2157 * @param expected_source Expected source of messages 2158 * @param expected_type Expected type of messages 2159 * @param expected_id Expected id of messages 2160 * @param expected_severity Expected severity of messages 2161 * @param expected_length Expected length of messages 2162 * @param expected_label Expected label of messages 2163 **/ 2164 void GroupsTest::inspectMessageLog(glw::GLenum expected_source, glw::GLenum expected_type, glw::GLuint expected_id, 2165 glw::GLenum expected_severity, glw::GLsizei expected_length, 2166 const glw::GLchar* expected_label) const 2167 { 2168 static const size_t bufSize = 32; 2169 static const size_t read_messages = 1; 2170 2171 GLchar messageLog[bufSize]; 2172 GLenum source; 2173 GLenum type; 2174 GLuint id; 2175 GLenum severity; 2176 GLsizei length; 2177 2178 GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, &source /* sources */, 2179 &type /* types */, &id /* ids */, &severity /* severities */, 2180 &length /* lengths */, messageLog /* messageLog */); 2181 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog"); 2182 2183 if (0 == ret) 2184 { 2185 TCU_FAIL("GetDebugMessageLog returned 0 messages"); 2186 } 2187 2188 if (expected_source != source) 2189 { 2190 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Got message with invalid source: " << source 2191 << ", expected " << expected_source << tcu::TestLog::EndMessage; 2192 2193 TCU_FAIL("Invalid source of message"); 2194 } 2195 2196 if (expected_type != type) 2197 { 2198 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Got message with invalid type: " << type 2199 << ", expected " << expected_type << tcu::TestLog::EndMessage; 2200 2201 TCU_FAIL("Invalid type of message"); 2202 } 2203 2204 if (expected_id != id) 2205 { 2206 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Got message with invalid id: " << id 2207 << ", expected " << expected_id << tcu::TestLog::EndMessage; 2208 2209 TCU_FAIL("Invalid id of message"); 2210 } 2211 2212 if (expected_severity != severity) 2213 { 2214 m_context.getTestContext().getLog() << tcu::TestLog::Message 2215 << "Got message with invalid severity: " << severity << ", expected " 2216 << expected_severity << tcu::TestLog::EndMessage; 2217 2218 TCU_FAIL("Invalid severity of message"); 2219 } 2220 2221 // DebugMessageInsert's length does not include null-terminated character (if length is positive) 2222 // But GetDebugMessageLog's length include null-terminated character 2223 // OpenGL 4.5 Core Spec, Page 530 and Page 535 2224 if (expected_length + 1 != length) 2225 { 2226 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Got message with invalid length: " << length 2227 << ", expected " << expected_length << tcu::TestLog::EndMessage; 2228 2229 TCU_FAIL("Invalid length of message"); 2230 } 2231 2232 if (0 != strcmp(expected_label, messageLog)) 2233 { 2234 m_context.getTestContext().getLog() << tcu::TestLog::Message 2235 << "Got message with invalid message: " << messageLog << ", expected " 2236 << expected_label << tcu::TestLog::EndMessage; 2237 2238 TCU_FAIL("Invalid message"); 2239 } 2240 } 2241 2242 /** Verifies that message log is empty 2243 * 2244 **/ 2245 void GroupsTest::verifyEmptyLog() const 2246 { 2247 static const size_t bufSize = 32; 2248 static const size_t read_messages = 1; 2249 2250 GLchar messageLog[bufSize]; 2251 GLenum source; 2252 GLenum type; 2253 GLuint id; 2254 GLenum severity; 2255 GLsizei length; 2256 2257 GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, &source /* sources */, 2258 &type /* types */, &id /* ids */, &severity /* severities */, 2259 &length /* lengths */, messageLog /* messageLog */); 2260 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog"); 2261 2262 if (0 != ret) 2263 { 2264 TCU_FAIL("GetDebugMessageLog returned unexpected messages"); 2265 } 2266 } 2267 2268 /** Constructor 2269 * 2270 * @param context Test context 2271 * @param is_debug Selects if debug or non-debug context should be used 2272 * @param name Name of test 2273 **/ 2274 SynchronousCallsTest::SynchronousCallsTest(deqp::Context& context) 2275 : TestCase(context, "synchronous_calls", "Verifies that messages can be received") 2276 , TestBase(context, true /* is_debug */) 2277 { 2278 /* Create pthread_key_t visible to all threads 2279 * The key has value NULL associated with it in all existing 2280 * or about to be created threads 2281 */ 2282 m_uid = 0; 2283 } 2284 2285 /** Execute test 2286 * 2287 * @return tcu::TestNode::STOP 2288 **/ 2289 tcu::TestNode::IterateResult SynchronousCallsTest::iterate() 2290 { 2291 m_uid++; 2292 2293 /* associate some unique id with the current thread */ 2294 m_tls.set((void*)(deUintptr)m_uid); 2295 2296 static const GLchar label[] = "foo"; 2297 2298 GLuint buffer_id = 0; 2299 2300 /* Initialize render context */ 2301 TestBase::init(); 2302 2303 /* - set callback_executed to 0; */ 2304 int callback_executed = 0; 2305 2306 /* 2307 *- enable DEBUG_OUTPUT_SYNCHRONOUS; 2308 */ 2309 m_gl->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS); 2310 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable"); 2311 2312 /* 2313 * - register debug message callback with DebugMessageCallback; Provide the 2314 * instance of UserParam structure as <userParam>; Routine should do the 2315 * following: 2316 * * set callback_executed to 1; 2317 */ 2318 m_gl->debugMessageCallback(debug_proc, &callback_executed); 2319 try 2320 { 2321 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageCallback"); 2322 2323 /* 2324 * - insert a message with DebugMessageInsert; 2325 */ 2326 m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */, 2327 GL_DEBUG_SEVERITY_HIGH /* severity */, -1 /* length */, label); 2328 GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert"); 2329 2330 /* Make sure execution finished before we check results */ 2331 m_gl->finish(); 2332 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish"); 2333 2334 /* 2335 * - check if: 2336 * * callback_executed is set to 1; 2337 */ 2338 if (1 != callback_executed) 2339 { 2340 TCU_FAIL("callback_executed is not set to 1"); 2341 } 2342 2343 /* Check that the message was recorded by the current thread */ 2344 if ((deUintptr)(m_tls.get()) != m_uid) 2345 { 2346 TCU_FAIL("thread id stored by callback is not the same as \"test\" thread"); 2347 } 2348 2349 /* 2350 * - reset callback_executed; 2351 */ 2352 callback_executed = 0; 2353 2354 /* 2355 * - execute BindBufferBase with GL_ARRAY_BUFFER <target>, GL_INVALID_ENUM 2356 * error should be generated; 2357 */ 2358 m_gl->genBuffers(1, &buffer_id); 2359 GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenBuffers"); 2360 2361 m_gl->bindBufferBase(GL_ARRAY_BUFFER, 0 /* index */, buffer_id); 2362 if (GL_INVALID_ENUM != m_gl->getError()) 2363 { 2364 TCU_FAIL("Unexpected error generated"); 2365 } 2366 2367 /* Make sure execution finished before we check results */ 2368 m_gl->finish(); 2369 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish"); 2370 2371 /* 2372 * - test pass if: 2373 * * callback_executed is set to 0 - implementation does not send messages; 2374 * * callback_executed is set to 1 and thread_id is the same 2375 * as "test" thread - implementation sent message to proper thread; 2376 */ 2377 if (1 == callback_executed) 2378 { 2379 /* Check that the error was recorded by the current thread */ 2380 if ((deUintptr)(m_tls.get()) != m_uid) 2381 { 2382 TCU_FAIL("thread id stored by callback is not the same as \"test\" thread"); 2383 } 2384 } 2385 2386 /* Clean */ 2387 m_gl->deleteBuffers(1, &buffer_id); 2388 buffer_id = 0; 2389 } 2390 catch (const std::exception& exc) 2391 { 2392 if (0 != buffer_id) 2393 { 2394 m_gl->deleteBuffers(1, &buffer_id); 2395 buffer_id = 0; 2396 } 2397 2398 TCU_FAIL(exc.what()); 2399 } 2400 2401 /* Set result */ 2402 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2403 2404 /* Done */ 2405 TestBase::done(); 2406 2407 return tcu::TestNode::STOP; 2408 } 2409 2410 /** Destructor */ 2411 SynchronousCallsTest::~SynchronousCallsTest(void) 2412 { 2413 } 2414 2415 /** Debug callback used by the test, sets callback_executed to 1 and stores 0 to tls 2416 * 2417 * @param ignored 2418 * @param ignored 2419 * @param ignored 2420 * @param ignored 2421 * @param ignored 2422 * @param ignored 2423 * @param info Pointer to uint counter 2424 **/ 2425 void SynchronousCallsTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */, 2426 glw::GLenum /* severity */, glw::GLsizei /* length */, 2427 const glw::GLchar* /* message */, const void* info) 2428 { 2429 int* callback_executed = (int*)info; 2430 2431 *callback_executed = 1; 2432 } 2433 } /* KHRDebug */ 2434 2435 /** Constructor. 2436 * 2437 * @param context Rendering context. 2438 **/ 2439 KHRDebugTests::KHRDebugTests(deqp::Context& context) 2440 : TestCaseGroup(context, "khr_debug", "Verifies \"khr debug\" functionality") 2441 { 2442 /* Left blank on purpose */ 2443 } 2444 2445 /** Initializes a khr_debug test group. 2446 * 2447 **/ 2448 void KHRDebugTests::init(void) 2449 { 2450 addChild(new KHRDebug::APIErrorsTest(m_context, false, "api_errors_non_debug")); 2451 addChild(new KHRDebug::LabelsTest(m_context, false, "labels_non_debug")); 2452 addChild(new KHRDebug::ReceiveingMessagesTest(m_context)); 2453 addChild(new KHRDebug::GroupsTest(m_context)); 2454 addChild(new KHRDebug::APIErrorsTest(m_context, true, "api_errors_debug")); 2455 addChild(new KHRDebug::LabelsTest(m_context, true, "labels_debug")); 2456 addChild(new KHRDebug::SynchronousCallsTest(m_context)); 2457 } 2458 2459 } /* gl4cts namespace */ 2460