1 #ifndef _GL4CKHRDEBUGTESTS_HPP
2 #define _GL4CKHRDEBUGTESTS_HPP
3 /*-------------------------------------------------------------------------
4 * OpenGL Conformance Test Suite
5 * -----------------------------
7 * Copyright (c) 2015-2016 The Khronos Group Inc.
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
24 */ /*-------------------------------------------------------------------*/
27 * \file gl4cKHRDebugTests.hpp
28 * \brief Declares test classes for "KHR Debug" functionality.
29 */ /*-------------------------------------------------------------------*/
31 #include "glcTestCase.hpp"
32 #include "glwDefs.hpp"
34 #include "deThreadLocal.hpp"
50 /** Base of all test cases.
51 * Manages rendering context
57 TestBase(deqp::Context& context, bool is_debug);
61 /* Protected methods */
65 /* Protected fields */
66 const glw::Functions* m_gl;
67 const bool m_is_debug;
68 glu::RenderContext* m_rc;
76 deqp::Context& m_test_base_context;
77 glu::RenderContext* m_orig_rc;
80 /** Implementation of test APIErrors. Description follows:
82 * This test verifies that errors are generated as expected.
84 * This test should be executed for DEBUG and NON-DEBUG contexts.
86 * DebugMessageControl function should generate:
87 * - INVALID_ENUM when <source> is invalid;
88 * - INVALID_ENUM when <type> is invalid;
89 * - INVALID_ENUM when <severity> is invalid;
90 * - INVALID_VALUE when <count> is negative;
91 * - INVALID_OPERATION when <count> is not zero and <source> is DONT_CARE;
92 * - INVALID_OPERATION when <count> is not zero and <type> is DONT_CARE;
93 * - INVALID_OPERATION when <count> is not zero and <severity> is not
96 * GetDebugMessageLog function should generate:
97 * - INVALID_VALUE when <bufSize> is negative and messageLog is not NULL.
99 * DebugMessageInsert function should generate:
100 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or
101 * DEBUG_SOURCE_THIRD_PARTY;
102 * - INVALID_ENUM when <type> is invalid;
103 * - INVALID_ENUM when <severity> is invalid;
104 * - INVALID_VALUE when length of string <buf> is not less than
105 * MAX_DEBUG_MESSAGE_LENGTH.
107 * PushDebugGroup function should generate:
108 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or
109 * DEBUG_SOURCE_THIRD_PARTY;
110 * - INVALID_VALUE when length of string <message> is not less than
111 * MAX_DEBUG_MESSAGE_LENGTH;
112 * - STACK_OVERFLOW when stack contains MAX_DEBUG_GROUP_STACK_DEPTH entries.
114 * PopDebugGroup function should generate:
115 * - STACK_UNDERFLOW when stack contains no entries.
117 * ObjectLabel function should generate:
118 * - INVALID_ENUM when <identifier> is invalid;
119 * - INVALID_VALUE when if <name> is not valid object name of type specified by
121 * - INVALID_VALUE when length of string <label> is not less than
124 * GetObjectLabel function should generate:
125 * - INVALID_ENUM when <identifier> is invalid;
126 * - INVALID_VALUE when if <name> is not valid object name of type specified by
128 * - INVALID_VALUE when <bufSize> is negative.
130 * ObjectPtrLabel function should generate:
131 * - INVALID_VALUE when <ptr> is not the name of sync object;
132 * - INVALID_VALUE when length of string <label> is not less than
135 * GetObjectPtrLabel function should generate:
136 * - INVALID_VALUE when <ptr> is not the name of sync object;
137 * - INVALID_VALUE when <bufSize> is negative.
139 * GetPointerv function should generate:
140 * - INVALID_ENUM when <pname> is invalid.
142 class APIErrorsTest : public deqp::TestCase, public TestBase
146 APIErrorsTest(deqp::Context& context, bool is_debug, const glw::GLchar* name);
148 virtual ~APIErrorsTest()
152 /* Public methods inherited from TestCase */
153 virtual tcu::TestNode::IterateResult iterate(void);
156 /** Implementation of test Labels. Description follows:
158 * This test verifies that it is possible to assign and query labels.
160 * This test should be executed for DEBUG and NON-DEBUG contexts.
162 * For each valid object type:
163 * - create new object;
164 * - query label; It is expected that result will be an empty string and length
166 * - assign label to object;
167 * - query label; It is expected that result will be equal to the provided
168 * label and length will be correct;
169 * - query length only; Correct value is expected;
170 * - query label with <bufSize> less than actual length of label; It is
171 * expected that only <bufSize> characters will be stored in buffer (including
173 * - query label with <bufSize> equal zero; It is expected that buffer contents
174 * will not be modified;
175 * - assign empty string as label to object;
176 * - query label, it is expected that result will be an empty string and length
178 * - assign NULL as label to object;
179 * - query label, it is expected that result will be an empty string and length
183 class LabelsTest : public deqp::TestCase, public TestBase
187 LabelsTest(deqp::Context& context, bool is_debug, const glw::GLchar* name);
189 virtual ~LabelsTest()
193 /* Public methods inherited from TestCase */
194 virtual tcu::TestNode::IterateResult iterate(void);
197 /* Private routines */
198 static glw::GLuint createBuffer(const glw::Functions* gl, const glu::RenderContext* rc);
199 static glw::GLuint createFramebuffer(const glw::Functions* gl, const glu::RenderContext* rc);
200 static glw::GLuint createProgram(const glw::Functions* gl, const glu::RenderContext* rc);
201 static glw::GLuint createProgramPipeline(const glw::Functions* gl, const glu::RenderContext* rc);
202 static glw::GLuint createQuery(const glw::Functions* gl, const glu::RenderContext* rc);
203 static glw::GLuint createRenderbuffer(const glw::Functions* gl, const glu::RenderContext* rc);
204 static glw::GLuint createSampler(const glw::Functions* gl, const glu::RenderContext* rc);
205 static glw::GLuint createShader(const glw::Functions* gl, const glu::RenderContext* rc);
206 static glw::GLuint createTexture(const glw::Functions* gl, const glu::RenderContext* rc);
207 static glw::GLuint createTransformFeedback(const glw::Functions* gl, const glu::RenderContext* rc);
208 static glw::GLuint createVertexArray(const glw::Functions* gl, const glu::RenderContext* rc);
210 static glw::GLvoid deleteBuffer(const glw::Functions* gl, glw::GLuint id);
211 static glw::GLvoid deleteFramebuffer(const glw::Functions* gl, glw::GLuint id);
212 static glw::GLvoid deleteProgram(const glw::Functions* gl, glw::GLuint id);
213 static glw::GLvoid deleteProgramPipeline(const glw::Functions* gl, glw::GLuint id);
214 static glw::GLvoid deleteQuery(const glw::Functions* gl, glw::GLuint id);
215 static glw::GLvoid deleteRenderbuffer(const glw::Functions* gl, glw::GLuint id);
216 static glw::GLvoid deleteSampler(const glw::Functions* gl, glw::GLuint id);
217 static glw::GLvoid deleteShader(const glw::Functions* gl, glw::GLuint id);
218 static glw::GLvoid deleteTexture(const glw::Functions* gl, glw::GLuint id);
219 static glw::GLvoid deleteTransformFeedback(const glw::Functions* gl, glw::GLuint id);
220 static glw::GLvoid deleteVertexArray(const glw::Functions* gl, glw::GLuint id);
223 /** Implementation of test ReceiveingMessages. Description follows:
225 * This test verifies that it is possible to receive messages.
227 * This test should be executed for DEBUG contexts only.
229 * Callback used during the test should make use of <userParam> to inform the
230 * test about any calls.
233 * - verify that the state of DEBUG_OUTPUT is enabled as it should be by
235 * - verify that state of DEBUG_CALLBACK_FUNCTION and
236 * DEBUG_CALLBACK_USER_PARAM are NULL;
238 * - insert a message with DebugMessageInsert;
239 * - inspect message log to check if the message is reported;
240 * - inspect message log again, there should be no messages;
242 * - disable DEBUG_OUTPUT;
243 * - insert a message with DebugMessageInsert;
244 * - inspect message log again, there should be no messages;
246 * - enable DEBUG_OUTPUT;
247 * - register debug message callback with DebugMessageCallback;
248 * - verify that the state of DEBUG_CALLBACK_FUNCTION and
249 * DEBUG_CALLBACK_USER_PARAM are correct;
250 * - insert a message with DebugMessageInsert;
251 * - it is expected that debug message callback will be executed for
253 * - inspect message log to check there are no messages;
255 * - disable DEBUG_OUTPUT;
256 * - insert a message with DebugMessageInsert;
257 * - debug message callback should not be called;
258 * - inspect message log to check there are no messages;
260 * - enable DEBUG_OUTPUT;
261 * - execute DebugMessageControl with <type> DEBUG_TYPE_ERROR, <severity>
262 * DEBUG_SEVERITY_HIGH and <enabled> FALSE;
263 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR
264 * and <severity> DEBUG_SEVERITY_MEDIUM;
265 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
266 * and <severity> DEBUG_SEVERITY_HIGH;
267 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
268 * and <severity> DEBUG_SEVERITY_LOW;
269 * - debug message callback should not be called;
270 * - inspect message log to check there are no messages;
272 * - set NULL as debug message callback;
273 * - verify that state of DEBUG_CALLBACK_FUNCTION and
274 * DEBUG_CALLBACK_USER_PARAM are NULL;
275 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR
276 * and <severity> DEBUG_SEVERITY_MEDIUM;
277 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
278 * and <severity> DEBUG_SEVERITY_HIGH;
279 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
280 * and <severity> DEBUG_SEVERITY_LOW;
281 * - inspect message log to check there are no messages;
283 * - execute DebugMessageControl to enable messages of <type> DEBUG_TYPE_ERROR
284 * and <severity> DEBUG_SEVERITY_HIGH.
286 * - insert MAX_DEBUG_LOGGED_MESSAGES + 1 unique messages with
287 * DebugMessageInsert;
288 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that
289 * MAX_DEBUG_LOGGED_MESSAGES will be reported;
291 * If MAX_DEBUG_LOGGED_MESSAGES is greater than 1:
292 * - inspect first half of the message log by specifying proper <count>; Verify
293 * that messages are reported in order from the oldest to the newest; Check
294 * that <count> messages were stored into provided buffers;
295 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that <count> messages
296 * were removed from log;
297 * - inspect rest of the message log with <bufSize> too small to held last
298 * message; Verify that messages are reported in order from the oldest to the
299 * newest; Verify that maximum <bufSize> characters were written to
301 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that one message is
303 * - fetch the message and verify it is the newest one;
305 class ReceiveingMessagesTest : public deqp::TestCase, public TestBase
309 ReceiveingMessagesTest(deqp::Context& context);
311 virtual ~ReceiveingMessagesTest()
315 /* Public methods inherited from TestCase */
316 virtual tcu::TestNode::IterateResult iterate(void);
319 /* Private routines */
320 static void GLW_APIENTRY debug_proc(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity,
321 glw::GLsizei length, const glw::GLchar* message, const void* info);
323 void inspectCallbackCounter(glw::GLuint& callback_counter, glw::GLuint expected_number_of_messages) const;
325 void inspectDebugState(glw::GLboolean expected_state, glw::GLDEBUGPROC expected_callback,
326 glw::GLvoid* expected_user_info) const;
328 void inspectMessageLog(glw::GLuint expected_number_of_messages) const;
331 /** Implementation of test Groups. Description follows:
333 * This test verifies that debug message groups can be used to control which
334 * messages are being generated.
336 * This test should be executed for DEBUG contexts only.
339 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1;
341 * - insert message with <type> DEBUG_TYPE_ERROR;
342 * - inspect message log to check if the message is reported;
343 * - insert message with <type> DEBUG_TYPE_OTHER;
344 * - inspect message log to check if the message is reported;
346 * - push debug group with unique <id> and <message>;
347 * - inspect message log to check if the message about push is reported;
348 * - disable messages with <type> DEBUG_TYPE_ERROR;
349 * - insert message with <type> DEBUG_TYPE_ERROR;
350 * - inspect message log to check there are no messages;
351 * - insert message with <type> DEBUG_TYPE_OTHER;
352 * - inspect message log to check if the message is reported;
354 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
356 * - push debug group with unique <id> and <message>;
357 * - inspect message log to check if the message about push is reported;
358 * - disable messages with <type> DEBUG_TYPE_OTHER;
359 * - insert message with <type> DEBUG_TYPE_ERROR;
360 * - inspect message log to check there are no messages;
361 * - insert message with <type> DEBUG_TYPE_OTHER;
362 * - inspect message log to check there are no messages;
364 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 3;
367 * - inspect message log to check if the message about pop is reported and
368 * corresponds with the second push;
369 * - insert message with <type> DEBUG_TYPE_ERROR;
370 * - inspect message log to check there are no messages;
371 * - insert message with <type> DEBUG_TYPE_OTHER;
372 * - inspect message log to check if the message is reported;
374 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
377 * - inspect message log to check if the message about pop is reported and
378 * corresponds with the first push;
379 * - insert message with <type> DEBUG_TYPE_ERROR;
380 * - inspect message log to check if the message is reported;
381 * - insert message with <type> DEBUG_TYPE_OTHER;
382 * - inspect message log to check if the message is reported;
384 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1.
386 class GroupsTest : public deqp::TestCase, public TestBase
390 GroupsTest(deqp::Context& context);
392 virtual ~GroupsTest()
396 /* Public methods inherited from TestCase */
397 virtual tcu::TestNode::IterateResult iterate(void);
400 /* Private routines */
401 void inspectGroupStack(glw::GLuint expected_depth) const;
402 void inspectMessageLog(glw::GLenum expected_source, glw::GLenum expected_type, glw::GLuint expected_id,
403 glw::GLenum expected_severity, glw::GLsizei expected_length,
404 const glw::GLchar* expected_label) const;
405 void verifyEmptyLog() const;
408 /** Implementation of test SynchronousCalls. Description follows:
410 * This test verifies that implementation execute debug message callback in
411 * synchronous way when DEBUG_OUTPUT_SYNCHRONOUS is enabled.
413 * This test should be executed for DEBUG contexts only.
416 * - create an instance of the following structure
417 * - set callback_executed to 0;
418 * - enable DEBUG_OUTPUT_SYNCHRONOUS;
419 * - register debug message callback with DebugMessageCallback; Provide the
420 * instance of UserParam structure as <userParam>; Routine should do the
422 * * set callback_executed to 1;
424 * - insert a message with DebugMessageInsert;
426 * * callback_executed is set to 1;
427 * * the message is recorded by the current thread.
428 * - reset userParam object;
429 * - execute BindBufferBase with GL_ARRAY_BUFFER <target>, GL_INVALID_ENUM
430 * error should be generated;
432 * * callback_executed is set to 0 - implementation does not send messages;
433 * * callback_executed is set to 1 and thread_id is the same
434 * as "test" thread - implementation sent message to proper thread;
436 class SynchronousCallsTest : public deqp::TestCase, public TestBase
440 SynchronousCallsTest(deqp::Context& context);
441 ~SynchronousCallsTest(void);
443 /* Public methods inherited from TestCase */
444 virtual tcu::TestNode::IterateResult iterate(void);
447 /* Private routines */
448 static void GLW_APIENTRY debug_proc(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity,
449 glw::GLsizei length, const glw::GLchar* message, const void* info);
451 de::ThreadLocal m_tls;
456 /** Group class for khr debug conformance tests */
457 class KHRDebugTests : public deqp::TestCaseGroup
461 KHRDebugTests(deqp::Context& context);
463 virtual ~KHRDebugTests(void)
467 virtual void init(void);
470 /* Private methods */
471 KHRDebugTests(const KHRDebugTests& other);
472 KHRDebugTests& operator=(const KHRDebugTests& other);
477 #endif // _GL4CKHRDEBUGTESTS_HPP