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
48 using namespace glw;
49
50 namespace glcts
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 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 **/
cleanGroupStack(const Functions * gl)79 void 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 **/
cleanMessageLog(const Functions * gl)100 void 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 **/
fillGroupStack(const Functions * gl)122 void 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 **/
TestBase(tcu::TestContext & testContext,glu::ApiType apiType,bool is_debug)149 TestBase::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 **/
~TestBase()158 TestBase::~TestBase()
159 {
160 if (0 != m_rc)
161 {
162 done();
163 }
164 }
165
166 /** Initialize rendering context
167 **/
init()168 void 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 **/
initDebug()185 void 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 **/
initNonDebug()202 void 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 **/
done()219 void 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 **/
APIErrorsTest(tcu::TestContext & testCtx,glu::ApiType apiType,bool is_debug,const GLchar * name)234 APIErrorsTest::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 **/
iterate()244 tcu::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 **/
LabelsTest(tcu::TestContext & testCtx,glu::ApiType apiType,bool is_debug,const GLchar * name)663 LabelsTest::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 **/
670 struct 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 **/
iterate()682 tcu::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 **/
createBuffer(const Functions * gl,const glu::RenderContext * rc)882 GLuint 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 **/
createFramebuffer(const Functions * gl,const glu::RenderContext * rc)907 GLuint 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 **/
createProgram(const Functions * gl,const glu::RenderContext *)934 GLuint 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 **/
createProgramPipeline(const Functions * gl,const glu::RenderContext * rc)948 GLuint 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 **/
createQuery(const Functions * gl,const glu::RenderContext * rc)972 GLuint 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 **/
createRenderbuffer(const Functions * gl,const glu::RenderContext * rc)997 GLuint 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 **/
createSampler(const Functions * gl,const glu::RenderContext * rc)1023 GLuint 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 **/
createShader(const Functions * gl,const glu::RenderContext *)1048 GLuint 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 **/
createTexture(const Functions * gl,const glu::RenderContext * rc)1062 GLuint 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 **/
createTransformFeedback(const Functions * gl,const glu::RenderContext * rc)1087 GLuint 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 **/
createVertexArray(const Functions * gl,const glu::RenderContext * rc)1112 GLuint 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 **/
deleteBuffer(const Functions * gl,GLuint id)1137 GLvoid 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 **/
deleteFramebuffer(const Functions * gl,GLuint id)1148 GLvoid 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 **/
deleteProgram(const Functions * gl,GLuint id)1159 GLvoid 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 **/
deleteProgramPipeline(const Functions * gl,GLuint id)1170 GLvoid 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 **/
deleteQuery(const Functions * gl,GLuint id)1181 GLvoid 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 **/
deleteRenderbuffer(const Functions * gl,GLuint id)1192 GLvoid 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 **/
deleteSampler(const Functions * gl,GLuint id)1203 GLvoid 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 **/
deleteShader(const Functions * gl,GLuint id)1214 GLvoid 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 **/
deleteTexture(const Functions * gl,GLuint id)1225 GLvoid 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 **/
deleteTransformFeedback(const Functions * gl,GLuint id)1236 GLvoid 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 **/
deleteVertexArray(const Functions * gl,GLuint id)1247 GLvoid 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 **/
ReceivingMessagesTest(tcu::TestContext & testCtx,glu::ApiType apiType)1259 ReceivingMessagesTest::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 **/
iterate()1270 tcu::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 **/
debug_proc(glw::GLenum,glw::GLenum,glw::GLuint,glw::GLenum,glw::GLsizei,const glw::GLchar *,void * info)1798 void ReceivingMessagesTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */,
1799 glw::GLenum /* severity */, glw::GLsizei /* length */,
1800 const glw::GLchar* /* message */, 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 **/
inspectDebugState(GLboolean expected_state,GLDEBUGPROC expected_callback,GLvoid * expected_user_info) const1813 void 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 **/
inspectCallbackCounter(GLuint & callback_counter,GLuint expected_number_of_messages) const1852 void 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 **/
inspectMessageLog(GLuint expected_number_of_messages) const1871 void 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 **/
GroupsTest(tcu::TestContext & testCtx,glu::ApiType apiType)1904 GroupsTest::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 **/
iterate()1915 tcu::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 **/
inspectGroupStack(GLuint expected_depth) const2117 void 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 **/
inspectMessageLog(glw::GLenum expected_source,glw::GLenum expected_type,glw::GLuint expected_id,glw::GLenum expected_severity,glw::GLsizei expected_length,const glw::GLchar * expected_label) const2143 void 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 **/
verifyEmptyLog() const2224 void 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 **/
SynchronousCallsTest(tcu::TestContext & testCtx,glu::ApiType apiType)2253 SynchronousCallsTest::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 **/
iterate()2268 tcu::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 */
~SynchronousCallsTest(void)2390 SynchronousCallsTest::~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 **/
debug_proc(glw::GLenum,glw::GLenum,glw::GLuint,glw::GLenum,glw::GLsizei,const glw::GLchar *,void * info)2404 void SynchronousCallsTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */,
2405 glw::GLenum /* severity */, glw::GLsizei /* length */,
2406 const glw::GLchar* /* message */, 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 **/
KHRDebugTests(tcu::TestContext & testCtx,glu::ApiType apiType)2418 KHRDebugTests::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 **/
init(void)2429 void 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