Home | History | Annotate | Download | only in gl
      1 #ifndef _GL4CKHRDEBUGTESTS_HPP
      2 #define _GL4CKHRDEBUGTESTS_HPP
      3 /*-------------------------------------------------------------------------
      4  * OpenGL Conformance Test Suite
      5  * -----------------------------
      6  *
      7  * Copyright (c) 2015-2016 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  gl4cKHRDebugTests.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 gl4cts
     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(deqp::Context& context, 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 	deqp::Context&		m_test_base_context;
     77 	glu::RenderContext* m_orig_rc;
     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 deqp::TestCase, public TestBase
    143 {
    144 public:
    145 	/* Public methods */
    146 	APIErrorsTest(deqp::Context& context, bool is_debug, const glw::GLchar* name);
    147 
    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 deqp::TestCase, public TestBase
    184 {
    185 public:
    186 	/* Public methods */
    187 	LabelsTest(deqp::Context& context, bool is_debug, const glw::GLchar* name);
    188 
    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 ReceiveingMessages. 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 ReceiveingMessagesTest : public deqp::TestCase, public TestBase
    306 {
    307 public:
    308 	/* Public methods */
    309 	ReceiveingMessagesTest(deqp::Context& context);
    310 
    311 	virtual ~ReceiveingMessagesTest()
    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, const 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 deqp::TestCase, public TestBase
    387 {
    388 public:
    389 	/* Public methods */
    390 	GroupsTest(deqp::Context& context);
    391 
    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 deqp::TestCase, public TestBase
    437 {
    438 public:
    439 	/* Public methods */
    440 	SynchronousCallsTest(deqp::Context& context);
    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, const 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 deqp::TestCaseGroup
    458 {
    459 public:
    460 	/* Public methods */
    461 	KHRDebugTests(deqp::Context& context);
    462 
    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 
    475 } /* gl4cts */
    476 
    477 #endif // _GL4CKHRDEBUGTESTS_HPP
    478