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