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