• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GLCKHRDEBUGTESTS_HPP
2 #define _GLCKHRDEBUGTESTS_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2015-2018 The Khronos Group Inc.
8  *
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  *
21  */ /*!
22  * \file
23  * \brief
24  */ /*-------------------------------------------------------------------*/
25 
26 /**
27  * \file  glcKHRDebugTests.hpp
28  * \brief Declares test classes for "KHR Debug" functionality.
29  */ /*-------------------------------------------------------------------*/
30 
31 #include "glcTestCase.hpp"
32 #include "glwDefs.hpp"
33 
34 #include "deThreadLocal.hpp"
35 
36 namespace glu
37 {
38 class RenderContext;
39 }
40 
41 namespace glw
42 {
43 class Functions;
44 }
45 
46 namespace glcts
47 {
48 namespace KHRDebug
49 {
50 /** Base of all test cases.
51  * Manages rendering context
52  **/
53 class TestBase
54 {
55 public:
56 	/* Public methods */
57 	TestBase(tcu::TestContext& testContext, glu::ApiType apiType, bool is_debug);
58 	virtual ~TestBase();
59 
60 protected:
61 	/* Protected methods */
62 	void init();
63 	void done();
64 
65 	/* Protected fields */
66 	const glw::Functions* m_gl;
67 	const bool			  m_is_debug;
68 	glu::RenderContext*   m_rc;
69 
70 private:
71 	/* Private methods */
72 	void initDebug();
73 	void initNonDebug();
74 
75 	/* Private fields */
76 	tcu::TestContext&	m_testContext;
77 	glu::ApiType		m_apiType;
78 };
79 
80 /** Implementation of test APIErrors. Description follows:
81  *
82  * This test verifies that errors are generated as expected.
83  *
84  * This test should be executed for DEBUG and NON-DEBUG contexts.
85  *
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
94  * DONT_CARE.
95  *
96  * GetDebugMessageLog function should generate:
97  * - INVALID_VALUE when <bufSize> is negative and messageLog is not NULL.
98  *
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.
106  *
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.
113  *
114  * PopDebugGroup function should generate:
115  * - STACK_UNDERFLOW when stack contains no entries.
116  *
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
120  * <identifier>;
121  * - INVALID_VALUE when length of string <label> is not less than
122  * MAX_LABEL_LENGTH.
123  *
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
127  * <identifier>;
128  * - INVALID_VALUE when <bufSize> is negative.
129  *
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
133  * MAX_LABEL_LENGTH.
134  *
135  * GetObjectPtrLabel function should generate:
136  * - INVALID_VALUE when <ptr> is not the name of sync object;
137  * - INVALID_VALUE when <bufSize> is negative.
138  *
139  * GetPointerv function should generate:
140  * - INVALID_ENUM when <pname> is invalid.
141  **/
142 class APIErrorsTest : public TestBase, public tcu::TestCase
143 {
144 public:
145 	/* Public methods */
146 	APIErrorsTest(tcu::TestContext& testCtx, glu::ApiType apiType, bool is_debug, const glw::GLchar* name);
147 
~APIErrorsTest()148 	virtual ~APIErrorsTest()
149 	{
150 	}
151 
152 	/* Public methods inherited from TestCase */
153 	virtual tcu::TestNode::IterateResult iterate(void);
154 };
155 
156 /** Implementation of test Labels. Description follows:
157  *
158  * This test verifies that it is possible to assign and query labels.
159  *
160  * This test should be executed for DEBUG and NON-DEBUG contexts.
161  *
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
165  * will be zero;
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
172  * NULL);
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
177  * will be zero;
178  * - assign NULL as label to object;
179  * - query label, it is expected that result will be an empty string and length
180  * will be zero;
181  * - delete object.
182  **/
183 class LabelsTest : public tcu::TestCase, public TestBase
184 {
185 public:
186 	/* Public methods */
187 	LabelsTest(tcu::TestContext& testCtx, glu::ApiType apiType, bool is_debug, const glw::GLchar* name);
188 
~LabelsTest()189 	virtual ~LabelsTest()
190 	{
191 	}
192 
193 	/* Public methods inherited from TestCase */
194 	virtual tcu::TestNode::IterateResult iterate(void);
195 
196 private:
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);
209 
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);
221 };
222 
223 /** Implementation of test ReceivingMessages. Description follows:
224  *
225  * This test verifies that it is possible to receive messages.
226  *
227  * This test should be executed for DEBUG contexts only.
228  *
229  * Callback used during the test should make use of <userParam> to inform the
230  * test about any calls.
231  *
232  * Steps:
233  * - verify that the state of DEBUG_OUTPUT is enabled as it should be by
234  * default;
235  * - verify that state of DEBUG_CALLBACK_FUNCTION and
236  * DEBUG_CALLBACK_USER_PARAM are NULL;
237  *
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;
241  *
242  * - disable DEBUG_OUTPUT;
243  * - insert a message with DebugMessageInsert;
244  * - inspect message log again, there should be no messages;
245  *
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
252  * the message;
253  * - inspect message log to check there are no messages;
254  *
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;
259  *
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;
271  *
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;
282  *
283  * - execute DebugMessageControl to enable messages of <type> DEBUG_TYPE_ERROR
284  * and <severity> DEBUG_SEVERITY_HIGH.
285  *
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;
290  *
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
300  * <messageLog>;
301  * - check state of DEBUG_LOGGED_MESSAGES; It is expected that one message is
302  * available;
303  * - fetch the message and verify it is the newest one;
304  **/
305 class ReceivingMessagesTest : public tcu::TestCase, public TestBase
306 {
307 public:
308 	/* Public methods */
309 	ReceivingMessagesTest(tcu::TestContext& testCtx, glu::ApiType apiType);
310 
~ReceivingMessagesTest()311 	virtual ~ReceivingMessagesTest()
312 	{
313 	}
314 
315 	/* Public methods inherited from TestCase */
316 	virtual tcu::TestNode::IterateResult iterate(void);
317 
318 private:
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, void* info);
322 
323 	void inspectCallbackCounter(glw::GLuint& callback_counter, glw::GLuint expected_number_of_messages) const;
324 
325 	void inspectDebugState(glw::GLboolean expected_state, glw::GLDEBUGPROC expected_callback,
326 						   glw::GLvoid* expected_user_info) const;
327 
328 	void inspectMessageLog(glw::GLuint expected_number_of_messages) const;
329 };
330 
331 /** Implementation of test Groups. Description follows:
332  *
333  * This test verifies that debug message groups can be used to control which
334  * messages are being generated.
335  *
336  * This test should be executed for DEBUG contexts only.
337  *
338  * Steps:
339  * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1;
340  *
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;
345  *
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;
353  *
354  * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
355  *
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;
363  *
364  * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 3;
365  *
366  * - pop debug group;
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;
373  *
374  * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
375  *
376  * - pop debug group;
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;
383  *
384  * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1.
385  **/
386 class GroupsTest : public tcu::TestCase, public TestBase
387 {
388 public:
389 	/* Public methods */
390 	GroupsTest(tcu::TestContext& testCtx, glu::ApiType apiType);
391 
~GroupsTest()392 	virtual ~GroupsTest()
393 	{
394 	}
395 
396 	/* Public methods inherited from TestCase */
397 	virtual tcu::TestNode::IterateResult iterate(void);
398 
399 private:
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;
406 };
407 
408 /** Implementation of test SynchronousCalls. Description follows:
409  *
410  * This test verifies that implementation execute debug message callback in
411  * synchronous way when DEBUG_OUTPUT_SYNCHRONOUS is enabled.
412  *
413  * This test should be executed for DEBUG contexts only.
414  *
415  * Steps:
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
421  * following:
422  *   * set callback_executed to 1;
423  *   * store thread_id;
424  * - insert a message with DebugMessageInsert;
425  * - check if:
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;
431  * - test pass if:
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;
435  **/
436 class SynchronousCallsTest : public tcu::TestCase, public TestBase
437 {
438 public:
439 	/* Public methods */
440 	SynchronousCallsTest(tcu::TestContext& testCtx, glu::ApiType apiType);
441 	~SynchronousCallsTest(void);
442 
443 	/* Public methods inherited from TestCase */
444 	virtual tcu::TestNode::IterateResult iterate(void);
445 
446 private:
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, void* info);
450 
451 	de::ThreadLocal m_tls;
452 	deUint32		m_uid;
453 };
454 } /* KHRDebug */
455 
456 /** Group class for khr debug conformance tests */
457 class KHRDebugTests : public tcu::TestCaseGroup
458 {
459 public:
460 	/* Public methods */
461 	KHRDebugTests(tcu::TestContext& testCtx, glu::ApiType apiType);
462 
~KHRDebugTests(void)463 	virtual ~KHRDebugTests(void)
464 	{
465 	}
466 
467 	virtual void init(void);
468 
469 private:
470 	/* Private methods */
471 	KHRDebugTests(const KHRDebugTests& other);
472 	KHRDebugTests& operator=(const KHRDebugTests& other);
473 
474 	/* Private members */
475 	glu::ApiType m_apiType;
476 };
477 
478 } /* glcts */
479 
480 #endif // _GLCKHRDEBUGTESTS_HPP
481