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