1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program EGL Module 3 * --------------------------------------- 4 * 5 * Copyright 2017 The Android Open Source Project 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 Robustness tests for KHR_robustness. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "teglRobustnessTests.hpp" 25 26 #include "tcuTestLog.hpp" 27 #include "tcuStringTemplate.hpp" 28 29 #include "egluConfigFilter.hpp" 30 #include "egluStrUtil.hpp" 31 #include "egluUtil.hpp" 32 #include "eglwLibrary.hpp" 33 34 #include "gluStrUtil.hpp" 35 #include "gluShaderProgram.hpp" 36 #include "gluDrawUtil.hpp" 37 38 #include "glwFunctions.hpp" 39 #include "glwEnums.hpp" 40 41 #include "deSTLUtil.hpp" 42 #include "deStringUtil.hpp" 43 #include "deThread.hpp" 44 #include "deSharedPtr.hpp" 45 46 #include <set> 47 48 using std::string; 49 using std::vector; 50 using std::set; 51 using tcu::TestLog; 52 53 using namespace eglw; 54 55 DE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY == 0x8256); 56 DE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET == 0x8252); 57 DE_STATIC_ASSERT(GL_NO_RESET_NOTIFICATION == 0x8261); 58 59 namespace deqp 60 { 61 namespace egl 62 { 63 namespace 64 { 65 66 enum ContextResetType 67 { 68 CONTEXTRESETTYPE_INFINITE_LOOP, 69 CONTEXTRESETTYPE_SHADER_OOB, 70 CONTEXTRESETTYPE_FIXED_FUNC_OOB, 71 }; 72 73 enum ShaderType 74 { 75 SHADERTYPE_VERT, 76 SHADERTYPE_FRAG, 77 SHADERTYPE_COMPUTE, 78 SHADERTYPE_VERT_AND_FRAG, 79 }; 80 81 enum ReadWriteType 82 { 83 READWRITETYPE_READ, 84 READWRITETYPE_WRITE, 85 }; 86 87 enum ResourceType 88 { 89 RESOURCETYPE_UBO, 90 RESOURCETYPE_SSBO, 91 RESOURCETYPE_LOCAL_ARRAY, 92 }; 93 94 enum FixedFunctionType 95 { 96 FIXEDFUNCTIONTYPE_INDICES, 97 FIXEDFUNCTIONTYPE_VERTICES, 98 }; 99 100 enum RobustAccessType 101 { 102 ROBUSTACCESS_TRUE, 103 ROBUSTACCESS_FALSE, 104 }; 105 106 void requireEGLExtension (const Library& egl, EGLDisplay eglDisplay, const char* requiredExtension) 107 { 108 if (!eglu::hasExtension(egl, eglDisplay, requiredExtension)) 109 TCU_THROW(NotSupportedError, (string(requiredExtension) + " not supported").c_str()); 110 } 111 112 bool isWindow (const eglu::CandidateConfig& c) 113 { 114 return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT; 115 } 116 117 template <deUint32 Type> 118 bool renderable (const eglu::CandidateConfig& c) 119 { 120 return (c.renderableType() & Type) == Type; 121 } 122 123 eglu::ConfigFilter getRenderableFilter (deUint32 bits) 124 { 125 switch (bits) 126 { 127 case EGL_OPENGL_ES2_BIT: return renderable<EGL_OPENGL_ES2_BIT>; 128 case EGL_OPENGL_ES3_BIT: return renderable<EGL_OPENGL_ES3_BIT>; 129 case EGL_OPENGL_BIT: return renderable<EGL_OPENGL_BIT>; 130 default: 131 DE_FATAL("Unknown EGL bitfied value"); 132 return renderable<0>; 133 } 134 } 135 136 const char* eglResetNotificationStrategyToString (EGLint strategy) 137 { 138 switch (strategy) 139 { 140 case EGL_NO_RESET_NOTIFICATION_KHR: return "EGL_NO_RESET_NOTIFICATION_KHR"; 141 case EGL_LOSE_CONTEXT_ON_RESET_KHR: return "EGL_LOSE_CONTEXT_ON_RESET_KHR"; 142 default: 143 return "<Unknown>"; 144 } 145 } 146 147 void logAttribList (const EglTestContext& eglTestCtx, const EGLint* attribList) 148 { 149 const EGLint* iter = &(attribList[0]); 150 std::ostringstream attribListString; 151 152 while ((*iter) != EGL_NONE) 153 { 154 switch (*iter) 155 { 156 // case EGL_CONTEXT_CLIENT_VERSION: 157 case EGL_CONTEXT_MAJOR_VERSION_KHR: 158 iter++; 159 attribListString << "EGL_CONTEXT_CLIENT_VERSION, " << (*iter) << ", "; 160 iter++; 161 break; 162 163 case EGL_CONTEXT_MINOR_VERSION_KHR: 164 iter++; 165 attribListString << "EGL_CONTEXT_MINOR_VERSION_KHR, " << (*iter) << ", "; 166 iter++; 167 break; 168 169 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: 170 iter++; 171 attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, " 172 << eglResetNotificationStrategyToString(*iter) << ", "; 173 iter++; 174 break; 175 176 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: 177 iter++; 178 attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, "; 179 180 if (*iter == EGL_FALSE || *iter == EGL_TRUE) 181 attribListString << (*iter ? "EGL_TRUE" : "EGL_FALSE") << ", "; 182 else 183 attribListString << (*iter) << ", "; 184 iter++; 185 break; 186 187 default: 188 DE_FATAL("Unsupported attribute"); 189 } 190 } 191 192 attribListString << "EGL_NONE"; 193 eglTestCtx.getTestContext().getLog() << TestLog::Message 194 << "EGL attrib list: { " << attribListString.str() << " }\n\n" 195 << TestLog::EndMessage; 196 } 197 198 class RobustnessTestCase: public TestCase 199 { 200 public: 201 class Params 202 { 203 public: 204 Params (void) {}; 205 206 Params (const string& name, 207 const string& description, 208 const RobustAccessType& robustAccessType, 209 const ContextResetType& contextResetType, 210 const FixedFunctionType& fixedFunctionType); 211 212 Params (const string& name, 213 const string& description, 214 const ContextResetType& contextResetType, 215 const ShaderType& shaderType); 216 217 Params (const string& name, 218 const string& description, 219 const RobustAccessType& robustAccessType, 220 const ContextResetType& contextResetType, 221 const ShaderType& shaderType, 222 const ResourceType& resourceType, 223 const ReadWriteType& readWriteType); 224 225 const string& getName (void) const { return m_name; } 226 const string& getDescription (void) const { return m_description; } 227 const ContextResetType& getContextResetType (void) const { return m_contextResetType; } 228 const ShaderType& getShaderType (void) const { return m_shaderType; } 229 const ResourceType& getResourceType (void) const { return m_resourceType; } 230 const ReadWriteType& getReadWriteType (void) const { return m_readWriteType; } 231 const FixedFunctionType& getFixedFunctionType (void) const { return m_fixedFunctionType; } 232 const RobustAccessType& getRobustAccessType (void) const { return m_robustAccessType; } 233 234 private: 235 string m_name; 236 string m_description; 237 RobustAccessType m_robustAccessType; 238 ContextResetType m_contextResetType; 239 ShaderType m_shaderType; 240 ResourceType m_resourceType; 241 ReadWriteType m_readWriteType; 242 FixedFunctionType m_fixedFunctionType; 243 }; 244 245 RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description); 246 RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params); 247 ~RobustnessTestCase (void); 248 249 void checkRequiredEGLExtensions (const EGLint* attribList); 250 251 protected: 252 Params m_params; 253 EGLDisplay m_eglDisplay; 254 EGLConfig m_eglConfig; 255 EGLSurface m_eglSurface; 256 257 private: 258 void init (void); 259 void deinit (void); 260 void initEGLSurface (void); 261 EGLConfig getEGLConfig (void); 262 263 eglu::NativeWindow* m_window; 264 }; 265 266 RobustnessTestCase::Params::Params (const string& name, 267 const string& description, 268 const RobustAccessType& robustAccessType, 269 const ContextResetType& contextResetType, 270 const FixedFunctionType& fixedFunctionType) 271 : m_name (name) 272 , m_description (description) 273 , m_robustAccessType (robustAccessType) 274 , m_contextResetType (contextResetType) 275 , m_fixedFunctionType (fixedFunctionType) 276 { 277 } 278 279 RobustnessTestCase::Params::Params (const string& name, 280 const string& description, 281 const ContextResetType& contextResetType, 282 const ShaderType& shaderType) 283 : m_name (name) 284 , m_description (description) 285 , m_contextResetType (contextResetType) 286 , m_shaderType (shaderType) 287 { 288 } 289 290 RobustnessTestCase::Params::Params (const string& name, 291 const string& description, 292 const RobustAccessType& robustAccessType, 293 const ContextResetType& contextResetType, 294 const ShaderType& shaderType, 295 const ResourceType& resourceType, 296 const ReadWriteType& readWriteType) 297 : m_name (name) 298 , m_description (description) 299 , m_robustAccessType (robustAccessType) 300 , m_contextResetType (contextResetType) 301 , m_shaderType (shaderType) 302 , m_resourceType (resourceType) 303 , m_readWriteType (readWriteType) 304 { 305 } 306 307 RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description) 308 : TestCase (eglTestCtx, name, description) 309 , m_eglDisplay (EGL_NO_DISPLAY) 310 , m_eglConfig (0) 311 , m_eglSurface (EGL_NO_SURFACE) 312 , m_window (DE_NULL) 313 { 314 } 315 316 RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params) 317 : TestCase (eglTestCtx, name, description) 318 , m_params (params) 319 , m_eglDisplay (EGL_NO_DISPLAY) 320 , m_eglConfig (0) 321 , m_eglSurface (EGL_NO_SURFACE) 322 , m_window (DE_NULL) 323 { 324 } 325 326 RobustnessTestCase::~RobustnessTestCase (void) 327 { 328 deinit(); 329 } 330 331 void RobustnessTestCase::init (void) 332 { 333 m_eglDisplay = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()); 334 m_eglConfig = getEGLConfig(); 335 336 initEGLSurface(); 337 } 338 339 void RobustnessTestCase::deinit (void) 340 { 341 const Library& egl = m_eglTestCtx.getLibrary(); 342 343 if (m_eglSurface != EGL_NO_SURFACE) 344 { 345 egl.destroySurface(m_eglDisplay, m_eglSurface); 346 m_eglSurface = EGL_NO_SURFACE; 347 } 348 if (m_eglDisplay != EGL_NO_DISPLAY) 349 { 350 egl.terminate(m_eglDisplay); 351 m_eglDisplay = EGL_NO_DISPLAY; 352 } 353 354 delete m_window; 355 m_window = DE_NULL; 356 } 357 358 EGLConfig RobustnessTestCase::getEGLConfig (void) 359 { 360 eglu::FilterList filters; 361 filters << isWindow << getRenderableFilter(EGL_OPENGL_ES3_BIT); 362 return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, filters); 363 } 364 365 void RobustnessTestCase::initEGLSurface (void) 366 { 367 EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), bindAPI(EGL_OPENGL_ES_API)); 368 369 const eglu::NativeWindowFactory& factory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); 370 371 const eglu::WindowParams windowParams = eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine())); 372 m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL, windowParams); 373 m_eglSurface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL); 374 } 375 376 glu::ApiType paramsToApiType (const RobustnessTestCase::Params& params) 377 { 378 EGLint minorVersion = 0; 379 if (params.getShaderType() == SHADERTYPE_COMPUTE || 380 params.getResourceType() == RESOURCETYPE_SSBO || 381 params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB) 382 { 383 minorVersion = 1; 384 } 385 386 return glu::ApiType::es(3, minorVersion); 387 } 388 389 void RobustnessTestCase::checkRequiredEGLExtensions (const EGLint* attribList) 390 { 391 set<string> requiredExtensions; 392 vector<string> extensions = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_eglDisplay); 393 394 { 395 const EGLint* iter = attribList; 396 397 while ((*iter) != EGL_NONE) 398 { 399 switch (*iter) 400 { 401 case EGL_CONTEXT_MAJOR_VERSION_KHR: iter++; 402 iter++; 403 break; 404 405 case EGL_CONTEXT_MINOR_VERSION_KHR: 406 iter++; 407 requiredExtensions.insert("EGL_KHR_create_context"); 408 iter++; 409 break; 410 411 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: 412 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: 413 iter++; 414 requiredExtensions.insert("EGL_EXT_create_context_robustness"); 415 iter++; 416 break; 417 418 default: 419 DE_ASSERT(DE_FALSE); 420 } 421 } 422 } 423 424 for (std::set<string>::const_iterator reqExt = requiredExtensions.begin(); reqExt != requiredExtensions.end(); ++reqExt) 425 { 426 if (!de::contains(extensions.begin(), extensions.end(), *reqExt)) 427 { 428 const char* const extension = reqExt->c_str(); 429 requireEGLExtension(m_eglTestCtx.getLibrary(), m_eglDisplay, extension); 430 } 431 } 432 } 433 434 void checkRequiredGLSupport (const glw::Functions& gl, glu::ApiType requiredApi) 435 { 436 if (!glu::hasExtension(gl, requiredApi, "GL_KHR_robustness") && !glu::hasExtension(gl, requiredApi, "GL_EXT_robustness")) 437 { 438 TCU_THROW(NotSupportedError, (string("GL_KHR_robustness and GL_EXT_robustness") + " not supported").c_str()); 439 } 440 else 441 { 442 int realMinorVersion = 0; 443 gl.getIntegerv(GL_MINOR_VERSION, &realMinorVersion); 444 GLU_EXPECT_NO_ERROR(gl.getError(), "Get minor version failed"); 445 446 if (realMinorVersion < requiredApi.getMinorVersion()) 447 TCU_THROW(NotSupportedError, "Test case requires GLES 3.1"); 448 } 449 } 450 451 void checkGLSupportForParams (const glw::Functions& gl, const RobustnessTestCase::Params& params) 452 { 453 int minorVersion = 0; 454 if (params.getShaderType() == SHADERTYPE_COMPUTE || 455 params.getResourceType() == RESOURCETYPE_SSBO || 456 params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB) 457 { 458 minorVersion = 1; 459 } 460 checkRequiredGLSupport(gl, glu::ApiType::es(3, minorVersion)); 461 } 462 463 class RenderingContext 464 { 465 public: 466 RenderingContext (const EglTestContext& eglTestCtx, 467 const EGLint* attribList, 468 const EGLConfig& config, 469 const EGLDisplay& display, 470 const EGLContext& sharedContext); 471 ~RenderingContext (void); 472 473 void initGLFunctions (glw::Functions* gl, const glu::ApiType apiType); 474 void makeCurrent (const EGLSurface& surface); 475 EGLContext getContext (void); 476 477 private: 478 const EglTestContext& m_eglTestCtx; 479 const EGLint* m_attribList; 480 const EGLConfig& m_config; 481 const EGLDisplay& m_display; 482 const Library& m_egl; 483 484 EGLContext m_context; 485 486 void createContext (const EGLConfig& sharedConfig); 487 void destroyContext (void); 488 489 RenderingContext (const RenderingContext&); 490 RenderingContext& operator= (const RenderingContext&); 491 }; 492 493 RenderingContext::RenderingContext (const EglTestContext& eglTestCtx, 494 const EGLint* attribList, 495 const EGLConfig& config, 496 const EGLDisplay& display, 497 const EGLContext& sharedContext) 498 : m_eglTestCtx (eglTestCtx) 499 , m_attribList (attribList) 500 , m_config (config) 501 , m_display (display) 502 , m_egl (eglTestCtx.getLibrary()) 503 , m_context (EGL_NO_CONTEXT) 504 { 505 logAttribList(eglTestCtx, m_attribList); 506 createContext(sharedContext); 507 } 508 509 RenderingContext::~RenderingContext (void) 510 { 511 destroyContext(); 512 } 513 514 void RenderingContext::createContext (const EGLConfig& sharedContext) 515 { 516 m_context = m_egl.createContext(m_display, m_config, sharedContext, m_attribList); 517 EGLU_CHECK_MSG(m_egl, "eglCreateContext()"); 518 } 519 520 void RenderingContext::destroyContext (void) 521 { 522 EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); 523 524 if (m_context != EGL_NO_CONTEXT) 525 m_egl.destroyContext(m_display, m_context); 526 } 527 528 void RenderingContext::makeCurrent (const EGLSurface& surface) 529 { 530 EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, surface, surface, m_context)); 531 } 532 533 void RenderingContext::initGLFunctions (glw::Functions *gl, const glu::ApiType apiType) 534 { 535 // \todo [2017-03-23 pyry] Current version has 2 somewhat ugly hacks: 536 // 537 // 1) Core functions are loaded twice. We need glGetString(i) to query supported 538 // extensions to determine if we need to load EXT or KHR-suffixed robustness 539 // functions. This could be fixed by exposing glw::FunctionLoader in EglTestContext 540 // for example. 541 // 542 // 2) We assume that calling code will check for KHR_robustness or EXT_robustness 543 // support after calling initGLFunctions(). We could move the check here. 544 545 m_eglTestCtx.initGLFunctions(gl, apiType); 546 547 { 548 const char* const robustnessExt = glu::hasExtension(*gl, apiType, "GL_KHR_robustness") ? "GL_KHR_robustness" : "GL_EXT_robustness"; 549 const char* const extensions[] = { robustnessExt }; 550 551 m_eglTestCtx.initGLFunctions(gl, apiType, DE_LENGTH_OF_ARRAY(extensions), &extensions[0]); 552 } 553 } 554 555 EGLContext RenderingContext::getContext (void) 556 { 557 return m_context; 558 } 559 560 class ContextReset 561 { 562 public: 563 ContextReset (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType); 564 ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType); 565 ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType); 566 567 virtual ~ContextReset (void) {}; 568 569 virtual void setup (void) = 0; 570 virtual void draw (void) = 0; 571 virtual void teardown (void) = 0; 572 573 void finish (void); 574 void createSyncObject (void); 575 glw::GLint getSyncStatus (void); 576 577 void beginQuery (void); 578 void endQuery (void); 579 glw::GLint getError (void); 580 glw::GLint getGraphicsResetStatus (void); 581 glw::GLuint getQueryAvailability (void); 582 583 glw::GLsync getSyncObject (void) const { return m_sync; } 584 glw::GLuint getQueryID (void) const { return m_queryID; } 585 586 glw::Functions& m_gl; 587 tcu::TestLog& m_log; 588 ShaderType m_shaderType; 589 ResourceType m_resourceType; 590 ReadWriteType m_readWriteType; 591 FixedFunctionType m_fixedFunctionType; 592 593 private: 594 ContextReset (const ContextReset&); 595 ContextReset& operator= (const ContextReset&); 596 597 glw::GLuint m_queryID; 598 glw::GLsync m_sync; 599 }; 600 601 ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType) 602 : m_gl (gl) 603 , m_log (log) 604 , m_fixedFunctionType (fixedFunctionType) 605 { 606 } 607 608 ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType) 609 : m_gl (gl) 610 , m_log (log) 611 , m_shaderType (shaderType) 612 , m_resourceType (resourceType) 613 , m_readWriteType (readWriteType) 614 { 615 } 616 617 ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType) 618 : m_gl (gl) 619 , m_log (log) 620 , m_shaderType (shaderType) 621 { 622 } 623 624 void ContextReset::finish (void) 625 { 626 GLU_CHECK_GLW_CALL(m_gl, finish()); 627 } 628 629 void ContextReset::createSyncObject (void) 630 { 631 m_sync = m_gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 632 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFenceSync()"); 633 } 634 635 glw::GLint ContextReset::getError (void) 636 { 637 glw::GLint error; 638 error = m_gl.getError(); 639 640 return error; 641 } 642 643 glw::GLint ContextReset::getGraphicsResetStatus (void) 644 { 645 glw::GLint resetStatus; 646 resetStatus = m_gl.getGraphicsResetStatus(); 647 648 return resetStatus; 649 } 650 651 glw::GLint ContextReset::getSyncStatus (void) 652 { 653 glw::GLint syncStatus; 654 m_gl.getSynciv(m_sync, GL_SYNC_STATUS, sizeof(glw::GLint), NULL, &syncStatus); 655 656 return syncStatus; 657 } 658 659 void ContextReset::beginQuery (void) 660 { 661 GLU_CHECK_GLW_CALL(m_gl, genQueries(1, &m_queryID)); 662 GLU_CHECK_GLW_CALL(m_gl, beginQuery(GL_ANY_SAMPLES_PASSED, m_queryID)); 663 } 664 665 void ContextReset::endQuery (void) 666 { 667 GLU_CHECK_GLW_CALL(m_gl, endQuery(GL_ANY_SAMPLES_PASSED)); 668 } 669 670 glw::GLuint ContextReset::getQueryAvailability (void) 671 { 672 glw::GLuint queryReady = GL_FALSE; 673 m_gl.getQueryObjectuiv(m_queryID, GL_QUERY_RESULT_AVAILABLE, &queryReady); 674 675 return queryReady; 676 } 677 678 class InfiniteLoop : public ContextReset 679 { 680 public: 681 InfiniteLoop (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType); 682 ~InfiniteLoop (void); 683 684 virtual void setup (void); 685 virtual void draw (void); 686 virtual void teardown (void); 687 688 private: 689 glu::ProgramSources genComputeSource (void); 690 glu::ProgramSources genNonComputeSource (void); 691 glu::ProgramSources genSources (void); 692 693 glw::GLuint m_outputBuffer; 694 glw::GLuint m_coordinatesBuffer; 695 glw::GLint m_coordLocation; 696 }; 697 698 InfiniteLoop::InfiniteLoop (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType) 699 : ContextReset(gl, log, shaderType) 700 , m_outputBuffer (0) 701 , m_coordinatesBuffer (0) 702 , m_coordLocation (0) 703 { 704 } 705 706 InfiniteLoop::~InfiniteLoop (void) 707 { 708 try 709 { 710 // Reset GL_CONTEXT_LOST error before destroying resources 711 m_gl.getGraphicsResetStatus(); 712 teardown(); 713 } 714 catch (...) 715 { 716 // Ignore GL errors from teardown() 717 } 718 } 719 720 glu::ProgramSources InfiniteLoop::genSources(void) 721 { 722 if (m_shaderType == SHADERTYPE_COMPUTE) 723 return genComputeSource(); 724 else 725 return genNonComputeSource(); 726 } 727 728 glu::ProgramSources InfiniteLoop::genComputeSource(void) 729 { 730 const char* const computeSource = 731 "#version 310 es\n" 732 "layout(local_size_x = 1, local_size_y = 1) in;\n" 733 "uniform highp int u_iterCount;\n" 734 "writeonly buffer Output { highp int b_output_int; };\n" 735 "void main ()\n" 736 "{\n" 737 " for (highp int i = 0; i < u_iterCount || u_iterCount < 0; ++i)\n" 738 " b_output_int = u_iterCount;\n" 739 "}\n"; 740 741 return glu::ProgramSources() << glu::ComputeSource(computeSource); 742 } 743 744 glu::ProgramSources InfiniteLoop::genNonComputeSource (void) 745 { 746 const bool isVertCase = m_shaderType == SHADERTYPE_VERT; 747 const bool isFragCase = m_shaderType == SHADERTYPE_FRAG; 748 const bool isVertAndFragment = m_shaderType == SHADERTYPE_VERT_AND_FRAG; 749 750 std::ostringstream vert, frag; 751 752 vert << "#version 300 es\n" 753 << "in highp vec2 a_position;\n"; 754 755 frag << "#version 300 es\n"; 756 757 vert << "uniform highp int u_iterCount;\n"; 758 if (isFragCase || isVertAndFragment) 759 { 760 vert << "flat out highp int v_iterCount;\n"; 761 frag << "flat in highp int v_iterCount;\n"; 762 } 763 764 if (isVertCase || isVertAndFragment) 765 { 766 vert << "out mediump vec4 v_color;\n"; 767 frag << "in mediump vec4 v_color;\n"; 768 } 769 770 frag << "out mediump vec4 o_color;\n"; 771 772 vert << "\nvoid main (void)\n{\n" 773 << " gl_Position = vec4(a_position, 0.0, 1.0);\n" 774 << " gl_PointSize = 1.0;\n"; 775 776 if (isFragCase || isVertAndFragment) 777 vert << " v_iterCount = u_iterCount;\n"; 778 779 frag << "\nvoid main (void)\n{\n"; 780 781 const std::string iterCount = (isVertCase ? "u_iterCount" : "v_iterCount"); 782 const std::string loopHeader = " for (highp int i = 0; i < " + iterCount + " || " + iterCount + " < 0; ++i)\n"; 783 const char* const body = "color = cos(sin(color*1.25)*0.8);"; 784 785 if (isVertAndFragment) 786 { 787 vert << " mediump vec4 color = " << "a_position.xyxy" << ";\n"; 788 vert << loopHeader << " " << body << "\n"; 789 790 frag << " mediump vec4 color = " << "gl_FragCoord" << ";\n"; 791 frag << loopHeader << " " << body << "\n"; 792 } 793 else 794 { 795 std::ostringstream& op = isVertCase ? vert : frag; 796 op << " mediump vec4 color = " << (isVertCase ? "a_position.xyxy" : "gl_FragCoord") << ";\n"; 797 op << loopHeader << " " << body << "\n"; 798 } 799 800 if (isVertCase || isVertAndFragment) 801 { 802 vert << " v_color = color;\n"; 803 frag << " o_color = v_color;\n"; 804 } 805 else 806 frag << " o_color = color;\n"; 807 808 vert << "}\n"; 809 frag << "}\n"; 810 811 return glu::ProgramSources() << glu::VertexSource(vert.str()) << glu::FragmentSource(frag.str()); 812 } 813 814 void InfiniteLoop::setup (void) 815 { 816 glu::ShaderProgram program (m_gl, genSources()); 817 m_log << program; 818 819 if (!program.isOk()) 820 TCU_FAIL("Failed to compile shader program"); 821 822 GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram())); 823 824 if (m_shaderType == SHADERTYPE_COMPUTE) 825 { 826 // Output buffer setup 827 m_outputBuffer = 0; 828 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_outputBuffer)); 829 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, m_outputBuffer)); 830 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), DE_NULL, GL_DYNAMIC_DRAW)); 831 GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_outputBuffer)); 832 } 833 else 834 { 835 const glw::GLfloat coords[] = 836 { 837 -1.0f, -1.0f, 838 +1.0f, -1.0f, 839 +1.0f, +1.0f, 840 -1.0f, +1.0f 841 }; 842 843 m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position"); 844 GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()"); 845 TCU_CHECK(m_coordLocation != (glw::GLint)-1); 846 847 // Load the vertex data 848 m_coordinatesBuffer = 0; 849 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer)); 850 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer)); 851 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW)); 852 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation)); 853 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL)); 854 } 855 856 glw::GLint iterCountLocation = m_gl.getUniformLocation(program.getProgram(), "u_iterCount"); 857 GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()"); 858 TCU_CHECK(iterCountLocation != (glw::GLint)-1); 859 860 // Set the iteration count (infinite) 861 glw::GLint iterCount = -1; 862 GLU_CHECK_GLW_CALL(m_gl, uniform1i(iterCountLocation, iterCount)); 863 } 864 865 void InfiniteLoop::draw (void) 866 { 867 if (m_shaderType == SHADERTYPE_COMPUTE) 868 m_gl.dispatchCompute(1, 1, 1); 869 else 870 { 871 const glw::GLushort indices[] = { 0, 1, 2, 2, 3, 0 }; 872 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); 873 } 874 } 875 876 void InfiniteLoop::teardown (void) 877 { 878 if (m_shaderType != SHADERTYPE_COMPUTE) 879 { 880 if (m_coordLocation) 881 { 882 GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation)); 883 m_coordLocation = 0; 884 } 885 } 886 887 if (m_outputBuffer) 888 { 889 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_outputBuffer)); 890 m_outputBuffer = 0; 891 } 892 893 if (m_coordinatesBuffer) 894 { 895 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer)); 896 m_coordinatesBuffer = 0; 897 } 898 899 GLU_CHECK_GLW_CALL(m_gl, useProgram(0)); 900 } 901 902 class FixedFunctionOOB : public ContextReset 903 { 904 public: 905 FixedFunctionOOB (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType); 906 ~FixedFunctionOOB (void); 907 908 struct TestConfig 909 { 910 int textureWidth; 911 int textureHeight; 912 }; 913 914 virtual void setup (void); 915 virtual void draw (void); 916 virtual void teardown (void); 917 918 private: 919 glu::ProgramSources genSources (void); 920 glw::GLuint m_coordinatesBuffer; 921 glw::GLint m_coordLocation; 922 }; 923 924 FixedFunctionOOB::FixedFunctionOOB (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType) 925 : ContextReset(gl, log, fixedFunctionType) 926 , m_coordinatesBuffer (0) 927 , m_coordLocation (0) 928 { 929 } 930 931 FixedFunctionOOB::~FixedFunctionOOB (void) 932 { 933 try 934 { 935 // Reset GL_CONTEXT_LOST error before destroying resources 936 m_gl.getGraphicsResetStatus(); 937 teardown(); 938 } 939 catch (...) 940 { 941 // Ignore GL errors from teardown() 942 } 943 } 944 945 glu::ProgramSources FixedFunctionOOB::genSources (void) 946 { 947 const char* const vert = 948 "#version 300 es\n" 949 "in highp vec4 a_position;\n" 950 "void main (void)\n" 951 "{\n" 952 " gl_Position = a_position;\n" 953 "}\n"; 954 955 const char* const frag = 956 "#version 300 es\n" 957 "layout(location = 0) out highp vec4 fragColor;\n" 958 "void main (void)\n" 959 "{\n" 960 " fragColor = vec4(1.0f);\n" 961 "}\n"; 962 963 return glu::ProgramSources() << glu::VertexSource(vert) << glu::FragmentSource(frag); 964 } 965 966 void FixedFunctionOOB::setup (void) 967 { 968 glu::ShaderProgram program(m_gl, genSources()); 969 970 m_log << program; 971 972 if (!program.isOk()) 973 TCU_FAIL("Failed to compile shader program"); 974 975 GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram())); 976 977 const glw::GLfloat coords[] = 978 { 979 -1.0f, -1.0f, 980 1.0f, -1.0f, 981 1.0f, 1.0f, 982 -1.0f, 1.0f 983 }; 984 985 m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position"); 986 GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()"); 987 TCU_CHECK(m_coordLocation != (glw::GLint)-1); 988 989 // Load the vertex data 990 m_coordinatesBuffer = 0; 991 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer)); 992 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer)); 993 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW)); 994 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation)); 995 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL)); 996 } 997 998 void FixedFunctionOOB::draw (void) 999 { 1000 const glw::GLint bad_indices[] = {0, 10, 100, 1000, 10000, 100000}; 1001 1002 if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_INDICES) 1003 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, bad_indices); 1004 else if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_VERTICES) 1005 m_gl.drawArrays(GL_TRIANGLES, 0, 1000); 1006 else 1007 DE_FATAL("Unknown fixed function type"); 1008 } 1009 1010 void FixedFunctionOOB::teardown (void) 1011 { 1012 if (m_coordLocation) 1013 { 1014 GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation)); 1015 m_coordLocation = 0; 1016 } 1017 1018 if (m_coordinatesBuffer) 1019 { 1020 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer)); 1021 m_coordinatesBuffer = 0; 1022 } 1023 1024 GLU_CHECK_GLW_CALL(m_gl, useProgram(0)); 1025 } 1026 1027 class ShadersOOB : public ContextReset 1028 { 1029 public: 1030 ShadersOOB (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType); 1031 ~ShadersOOB (void); 1032 1033 virtual void setup (void); 1034 virtual void draw (void); 1035 virtual void teardown (void); 1036 1037 private: 1038 static const int s_numBindings = 3; 1039 1040 glw::GLuint m_coordinatesBuffer; 1041 glw::GLint m_coordLocation; 1042 1043 bool m_isUBO; 1044 bool m_isRead; 1045 bool m_isLocalArray; 1046 std::vector<glw::GLuint> m_buffers; 1047 1048 std::string genVertexShader (const std::string& shaderDecl, const std::string& shaderBody); 1049 std::string genFragmentShader (const std::string& shaderDecl, const std::string& shaderBody); 1050 std::string genComputeShader (const std::string& shaderDecl, const std::string& shaderBody); 1051 1052 glu::ProgramSources genNonComputeSource (void); 1053 glu::ProgramSources genComputeSource (void); 1054 glu::ProgramSources genSources (void); 1055 }; 1056 1057 ShadersOOB::ShadersOOB (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType) 1058 : ContextReset(gl, log, shaderType, resourceType, readWriteType) 1059 , m_coordinatesBuffer (0) 1060 , m_coordLocation (0) 1061 , m_buffers (s_numBindings, 0) 1062 { 1063 m_isUBO = (m_resourceType == RESOURCETYPE_UBO); 1064 m_isLocalArray = (m_resourceType == RESOURCETYPE_LOCAL_ARRAY); 1065 m_isRead = (m_readWriteType == READWRITETYPE_READ); 1066 } 1067 1068 ShadersOOB::~ShadersOOB (void) 1069 { 1070 try 1071 { 1072 // Reset GL_CONTEXT_LOST error before destroying resources 1073 m_gl.getGraphicsResetStatus(); 1074 teardown(); 1075 } 1076 catch (...) 1077 { 1078 // Ignore GL errors from teardown() 1079 } 1080 } 1081 1082 std::string ShadersOOB::genVertexShader (const std::string& shaderDecl, const std::string& shaderBody) 1083 { 1084 static const char* const s_simpleVertexShaderSource = 1085 "#version 310 es\n" 1086 "in highp vec4 a_position;\n" 1087 "void main (void)\n" 1088 "{\n" 1089 " gl_Position = a_position;\n" 1090 "}\n"; 1091 1092 switch (m_shaderType) 1093 { 1094 case SHADERTYPE_VERT: 1095 case SHADERTYPE_VERT_AND_FRAG: 1096 { 1097 std::ostringstream vertexShaderSource; 1098 vertexShaderSource << "#version 310 es\n" 1099 << "in highp vec4 a_position;\n" 1100 << "out highp vec4 v_color;\n" 1101 << shaderDecl << "\n" 1102 << "void main (void)\n" 1103 << "{\n" 1104 << " highp vec4 color;\n" 1105 << shaderBody << "\n" 1106 << " v_color = color;\n" 1107 << " gl_Position = a_position;\n" 1108 << "}\n"; 1109 1110 return vertexShaderSource.str(); 1111 } 1112 1113 case SHADERTYPE_FRAG: 1114 return s_simpleVertexShaderSource; 1115 1116 default: 1117 DE_FATAL("Unknown shader type"); 1118 return ""; 1119 } 1120 } 1121 1122 std::string ShadersOOB::genFragmentShader (const std::string& shaderDecl, const std::string& shaderBody) 1123 { 1124 static const char* const s_simpleFragmentShaderSource = 1125 "#version 310 es\n" 1126 "in highp vec4 v_color;\n" 1127 "layout(location = 0) out highp vec4 fragColor;\n" 1128 "void main (void)\n" 1129 "{\n" 1130 " fragColor = v_color;\n" 1131 "}\n"; 1132 1133 switch (m_shaderType) 1134 { 1135 case SHADERTYPE_VERT: 1136 return s_simpleFragmentShaderSource; 1137 1138 case SHADERTYPE_FRAG: 1139 { 1140 std::ostringstream fragmentShaderSource; 1141 fragmentShaderSource << "#version 310 es\n" 1142 << "layout(location = 0) out highp vec4 fragColor;\n" 1143 << shaderDecl << "\n" 1144 << "void main (void)\n" 1145 << "{\n" 1146 << " highp vec4 color = vec4(0.0f);\n" 1147 << shaderBody << "\n" 1148 << " fragColor = color;\n" 1149 << "}\n"; 1150 1151 return fragmentShaderSource.str(); 1152 } 1153 case SHADERTYPE_VERT_AND_FRAG: 1154 { 1155 std::ostringstream fragmentShaderSource; 1156 fragmentShaderSource << "#version 310 es\n" 1157 << "in highp vec4 v_color;\n" 1158 << "layout(location = 0) out highp vec4 fragColor;\n" 1159 << shaderDecl << "\n" 1160 << "void main (void)\n" 1161 << "{\n" 1162 << " highp vec4 color = vec4(0.0f);\n" 1163 << shaderBody << "\n" 1164 << " fragColor = color;\n" 1165 << "}\n"; 1166 1167 return fragmentShaderSource.str(); 1168 } 1169 1170 default: 1171 DE_FATAL("Unknown shader type"); 1172 return ""; 1173 } 1174 } 1175 1176 std::string ShadersOOB::genComputeShader (const std::string& shaderDecl, const std::string& shaderBody) 1177 { 1178 std::ostringstream computeShaderSource; 1179 1180 computeShaderSource << "#version 310 es\n" 1181 << "layout(local_size_x = 1, local_size_y = 1) in;\n" 1182 << "\n" 1183 << "layout(binding = 0) buffer Output {\n" 1184 << " highp vec4 values;\n" 1185 << "} sb_out;\n" 1186 << "\n" 1187 << shaderDecl 1188 << "void main ()\n" 1189 << "{\n" 1190 << shaderBody 1191 << "}\n"; 1192 1193 return computeShaderSource.str(); 1194 } 1195 1196 glu::ProgramSources ShadersOOB::genNonComputeSource (void) 1197 { 1198 std::ostringstream shaderDecl; 1199 std::ostringstream shaderBody; 1200 1201 shaderDecl << "uniform highp int u_index;\n"; 1202 1203 if (m_isLocalArray) 1204 { 1205 const char* const readWriteStatement = (m_isRead) 1206 ? " color.x = color_out[u_index];\n" 1207 : " color[u_index] = color_out[0];\n"; 1208 1209 shaderBody << " highp float color_out[4] = float[4](0.25f, 0.5f, 0.75f, 1.0f);\n" 1210 << readWriteStatement; 1211 } 1212 else 1213 { 1214 const std::string resName = (m_isUBO) ? "ub_in" : "sb_in"; 1215 1216 shaderDecl << "layout(std140, binding = 0) " << ((m_isUBO) ? "uniform" : "buffer") << " Block\n" 1217 << "{\n" 1218 << " highp float color_out[4];\n" 1219 << "} " << resName << "[" << s_numBindings << "];\n"; 1220 1221 const std::string readWriteStatement = (m_isRead) 1222 ? " color.x = " + resName + "[0].color_out[u_index];\n" 1223 : " color[u_index] = " + resName + "[0].color_out[0];\n"; 1224 1225 shaderBody << readWriteStatement; 1226 } 1227 1228 return glu::ProgramSources() << glu::VertexSource(genVertexShader(shaderDecl.str(), shaderBody.str())) 1229 << glu::FragmentSource(genFragmentShader(shaderDecl.str(), shaderBody.str())); 1230 } 1231 1232 glu::ProgramSources ShadersOOB::genComputeSource (void) 1233 { 1234 std::ostringstream shaderDecl; 1235 std::ostringstream shaderBody; 1236 1237 shaderDecl << "uniform highp int u_index;\n"; 1238 1239 shaderBody << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n" 1240 << " uint groupNdx = size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x;\n"; 1241 1242 if (m_isLocalArray) 1243 { 1244 const char* const readWriteStatement = (m_isRead) 1245 ? " sb_out.values.x = values[u_index];\n" 1246 : " sb_out.values[u_index] = values.x;\n"; 1247 1248 shaderBody << " highp vec4 values = vec4(1.0f) * float(groupNdx);\n" 1249 << readWriteStatement; 1250 } 1251 else 1252 { 1253 const std::string resName = (m_isUBO) ? "ub_in" : "sb_in"; 1254 1255 shaderDecl << "layout(std140, binding = 1) " << ((m_isUBO) ? "uniform" : "buffer") << " Input\n" 1256 << "{\n" 1257 << " highp vec4 values;\n" 1258 << "} " << resName << "[" << s_numBindings << "];\n"; 1259 1260 std::string readWriteStatement = (m_isRead) 1261 ? " sb_out.values.x = " + resName + "[0].values[u_index] * float(groupNdx);\n" 1262 : " sb_out.values[u_index] = " + resName + "[0].values.x * float(groupNdx);\n"; 1263 1264 shaderBody << readWriteStatement; 1265 } 1266 1267 return glu::ProgramSources() << glu::ComputeSource(genComputeShader(shaderDecl.str(), shaderBody.str())); 1268 } 1269 1270 glu::ProgramSources ShadersOOB::genSources (void) 1271 { 1272 if (m_shaderType == SHADERTYPE_COMPUTE) 1273 return genComputeSource(); 1274 else 1275 return genNonComputeSource(); 1276 } 1277 1278 void ShadersOOB::setup (void) 1279 { 1280 if (!m_isUBO && !m_isLocalArray && (m_shaderType != SHADERTYPE_COMPUTE)) 1281 { 1282 // Check implementation limits for shader SSBO 1283 int shaderStorageBlockSupported = -1; 1284 const bool isVertex = (m_shaderType == SHADERTYPE_VERT || m_shaderType == SHADERTYPE_VERT_AND_FRAG) ? true : false; 1285 string shaderTypeStr = isVertex ? "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS" : "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS"; 1286 1287 GLU_CHECK_GLW_CALL(m_gl, getIntegerv(isVertex ? GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS : GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &shaderStorageBlockSupported)); 1288 1289 if (shaderStorageBlockSupported < (int)m_buffers.size()) 1290 TCU_THROW(NotSupportedError, ("Test requires " + shaderTypeStr + " >= " + de::toString((int)m_buffers.size()) + ", got " + de::toString(shaderStorageBlockSupported)).c_str()); 1291 } 1292 1293 glu::ShaderProgram program(m_gl, genSources()); 1294 1295 m_log << program; 1296 1297 if (!program.isOk()) 1298 TCU_FAIL("Failed to compile shader program"); 1299 1300 GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram())); 1301 1302 const glw::GLint indexLocation = m_gl.getUniformLocation(program.getProgram(), "u_index"); 1303 GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()"); 1304 TCU_CHECK(indexLocation != (glw::GLint)-1); 1305 1306 const glw::GLint index = -1; 1307 GLU_CHECK_GLW_CALL(m_gl, uniform1i(indexLocation, index)); 1308 1309 if (m_shaderType != SHADERTYPE_COMPUTE) 1310 { 1311 const glw::GLfloat coords[] = 1312 { 1313 -1.0f, -1.0f, 1314 +1.0f, -1.0f, 1315 +1.0f, +1.0f, 1316 -1.0f, +1.0f 1317 }; 1318 1319 // Setup vertices position 1320 m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position"); 1321 GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()"); 1322 TCU_CHECK(m_coordLocation != (glw::GLint)-1); 1323 1324 // Load the vertex data 1325 m_coordinatesBuffer = 0; 1326 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer)); 1327 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer)); 1328 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW)); 1329 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation)); 1330 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL)); 1331 } 1332 1333 // Create dummy data for filling buffer objects 1334 const std::vector<tcu::Vec4> refValues(s_numBindings, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f)); 1335 glw::GLenum resType = (m_isUBO) ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER; 1336 1337 if (!m_isLocalArray) 1338 { 1339 // Set up interface block of buffer bindings 1340 GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0])); 1341 1342 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx) 1343 { 1344 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(resType, m_buffers[bufNdx])); 1345 GLU_CHECK_GLW_CALL(m_gl, bufferData(resType, sizeof(tcu::Vec4), &(refValues[bufNdx]), GL_STATIC_DRAW)); 1346 GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(resType, bufNdx, m_buffers[bufNdx])); 1347 } 1348 } 1349 } 1350 1351 void ShadersOOB::draw (void) 1352 { 1353 if (m_shaderType == SHADERTYPE_COMPUTE) 1354 m_gl.dispatchCompute(1, 1, 1); 1355 else 1356 { 1357 const glw::GLuint indices[] = {0, 1, 2, 2, 3, 0}; 1358 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices); 1359 } 1360 } 1361 1362 void ShadersOOB::teardown (void) 1363 { 1364 if (m_shaderType != SHADERTYPE_COMPUTE) 1365 { 1366 if (m_coordLocation) 1367 { 1368 GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation)); 1369 m_coordLocation = 0; 1370 } 1371 } 1372 1373 if (m_coordinatesBuffer) 1374 { 1375 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer)); 1376 m_coordinatesBuffer = 0; 1377 } 1378 1379 if (!m_isLocalArray) 1380 { 1381 if (!m_buffers.empty()) 1382 { 1383 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0])); 1384 m_buffers.clear(); 1385 } 1386 } 1387 1388 GLU_CHECK_GLW_CALL(m_gl, useProgram(0)); 1389 } 1390 1391 class QueryRobustAccessCase : public RobustnessTestCase 1392 { 1393 public: 1394 QueryRobustAccessCase (EglTestContext& eglTestCtx, const char* name, const char* description) 1395 : RobustnessTestCase (eglTestCtx, name, description) {} 1396 1397 TestCase::IterateResult iterate (void) 1398 { 1399 TestLog& log = m_testCtx.getLog(); 1400 1401 log << tcu::TestLog::Message 1402 << "Check that after successfully creating a robust context the robust access query returned by glBooleanv() equals GL_TRUE\n\n" 1403 << tcu::TestLog::EndMessage; 1404 1405 const EGLint attribList[] = 1406 { 1407 EGL_CONTEXT_CLIENT_VERSION, 3, 1408 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1409 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, 1410 EGL_NONE 1411 }; 1412 1413 checkRequiredEGLExtensions(attribList); 1414 1415 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 1416 context.makeCurrent(m_eglSurface); 1417 1418 glw::Functions gl; 1419 { 1420 const glu::ApiType apiType(3, 0, glu::PROFILE_ES); 1421 context.initGLFunctions(&gl, apiType); 1422 checkRequiredGLSupport(gl, apiType); 1423 } 1424 1425 deUint8 robustAccessGL; 1426 gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL); 1427 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()"); 1428 1429 if (robustAccessGL != GL_TRUE) 1430 { 1431 log << TestLog::Message 1432 << "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '" << robustAccessGL << "' expected GL_TRUE." 1433 << TestLog::EndMessage; 1434 1435 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1436 return STOP; 1437 } 1438 1439 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1440 return STOP; 1441 } 1442 }; 1443 1444 class NoResetNotificationCase : public RobustnessTestCase 1445 { 1446 public: 1447 NoResetNotificationCase (EglTestContext& eglTestCtx, const char* name, const char* description) 1448 : RobustnessTestCase (eglTestCtx, name, description) {} 1449 1450 TestCase::IterateResult iterate (void) 1451 { 1452 TestLog& log = m_testCtx.getLog(); 1453 1454 log << tcu::TestLog::Message 1455 << "Check the reset notification strategy returned by glGetIntegerv() equals GL_NO_RESET_NOTIFICATION\n\n" 1456 << tcu::TestLog::EndMessage; 1457 1458 const EGLint attribList[] = 1459 { 1460 EGL_CONTEXT_CLIENT_VERSION, 3, 1461 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1462 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, 1463 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION, 1464 EGL_NONE 1465 }; 1466 1467 checkRequiredEGLExtensions(attribList); 1468 1469 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 1470 context.makeCurrent(m_eglSurface); 1471 1472 glw::Functions gl; 1473 { 1474 const glu::ApiType apiType(3, 0, glu::PROFILE_ES); 1475 context.initGLFunctions(&gl, apiType); 1476 checkRequiredGLSupport(gl, apiType); 1477 } 1478 1479 deUint8 robustAccessGL; 1480 gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL); 1481 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()"); 1482 1483 glw::GLint reset = 0; 1484 gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset); 1485 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()"); 1486 1487 if (reset != GL_NO_RESET_NOTIFICATION) 1488 { 1489 log << tcu::TestLog::Message 1490 << "Test failed! glGetIntegerv() returned wrong value. [" << glu::getErrorStr(reset) << ", expected " << glu::getErrorStr(GL_NO_RESET_NOTIFICATION) << "]" 1491 << tcu::TestLog::EndMessage; 1492 1493 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1494 return STOP; 1495 } 1496 1497 GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus()); 1498 1499 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1500 return STOP; 1501 } 1502 }; 1503 1504 class LoseContextOnResetCase : public RobustnessTestCase 1505 { 1506 public: 1507 LoseContextOnResetCase (EglTestContext& eglTestCtx, const char* name, const char* description) 1508 : RobustnessTestCase(eglTestCtx, name, description) {} 1509 1510 TestCase::IterateResult iterate (void) 1511 { 1512 TestLog& log = m_testCtx.getLog(); 1513 1514 log << tcu::TestLog::Message 1515 << "Check the reset notification strategy returned by glGetIntegerv() equals GL_LOSE_CONTEXT_ON_RESET\n\n" 1516 << tcu::TestLog::EndMessage; 1517 1518 const EGLint attribList[] = 1519 { 1520 EGL_CONTEXT_CLIENT_VERSION, 3, 1521 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1522 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, 1523 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET, 1524 EGL_NONE 1525 }; 1526 1527 checkRequiredEGLExtensions(attribList); 1528 1529 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 1530 context.makeCurrent(m_eglSurface); 1531 1532 glw::Functions gl; 1533 { 1534 const glu::ApiType apiType(3, 0, glu::PROFILE_ES); 1535 context.initGLFunctions(&gl, apiType); 1536 checkRequiredGLSupport(gl, apiType); 1537 } 1538 glw::GLint reset = 0; 1539 gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset); 1540 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()"); 1541 1542 if (reset != GL_LOSE_CONTEXT_ON_RESET) 1543 { 1544 log << tcu::TestLog::Message 1545 << "Test failed! glGetIntegerv() returned wrong value. [" << reset << ", expected " << glu::getErrorStr(GL_LOSE_CONTEXT_ON_RESET) << "]" 1546 << tcu::TestLog::EndMessage; 1547 1548 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1549 return STOP; 1550 } 1551 1552 log << tcu::TestLog::Message 1553 << "Check the graphics reset status returned by glGetGraphicsResetStatus() " 1554 << "equals GL_NO_ERROR\n" 1555 << tcu::TestLog::EndMessage; 1556 1557 GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus()); 1558 1559 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1560 return STOP; 1561 } 1562 }; 1563 1564 de::SharedPtr<ContextReset> contextResetFactory (const RobustnessTestCase::Params params, glw::Functions& gl, tcu::TestLog& log) 1565 { 1566 if (params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP) 1567 return de::SharedPtr<ContextReset>(new InfiniteLoop(gl, log, params.getShaderType())); 1568 1569 if (params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB) 1570 return de::SharedPtr<ContextReset>(new FixedFunctionOOB(gl, log, params.getFixedFunctionType())); 1571 1572 if (params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB) 1573 return de::SharedPtr<ContextReset>(new ShadersOOB(gl, log, params.getShaderType(), params.getResourceType(), params.getReadWriteType())); 1574 else 1575 { 1576 DE_FATAL("Unknown context reset type"); 1577 return de::SharedPtr<ContextReset>(DE_NULL); 1578 } 1579 } 1580 1581 class ContextResetCase : public RobustnessTestCase 1582 { 1583 1584 public: 1585 ContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params); 1586 virtual ~ContextResetCase (void) {}; 1587 1588 virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset) = 0; 1589 virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset) = 0; 1590 virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset) = 0; 1591 1592 TestCase::IterateResult iterate (void); 1593 void execute (glw::Functions& gl); 1594 1595 private: 1596 ContextResetCase (const ContextResetCase&); 1597 ContextResetCase& operator= (const ContextResetCase&); 1598 }; 1599 1600 ContextResetCase::ContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params) 1601 : RobustnessTestCase (eglTestCtx, name, description, params) {} 1602 1603 TestCase::IterateResult ContextResetCase::iterate (void) 1604 { 1605 glw::Functions gl; 1606 1607 const EGLint attribList[] = 1608 { 1609 EGL_CONTEXT_CLIENT_VERSION, 3, 1610 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1611 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, (m_params.getRobustAccessType() == ROBUSTACCESS_TRUE) ? EGL_TRUE : EGL_FALSE, 1612 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET, 1613 EGL_NONE 1614 }; 1615 1616 checkRequiredEGLExtensions(attribList); 1617 1618 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 1619 context.makeCurrent(m_eglSurface); 1620 1621 { 1622 const glu::ApiType apiType = paramsToApiType(m_params); 1623 context.initGLFunctions(&gl, apiType); 1624 checkGLSupportForParams(gl, m_params); 1625 } 1626 1627 execute(gl); 1628 1629 return STOP; 1630 } 1631 1632 void ContextResetCase::execute (glw::Functions& gl) 1633 { 1634 de::SharedPtr<ContextReset> contextReset = contextResetFactory(m_params, gl, m_testCtx.getLog()); 1635 glw::GLboolean isContextRobust = GL_FALSE; 1636 1637 GLU_CHECK_GLW_CALL(gl, getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &isContextRobust)); 1638 provokeReset(contextReset); 1639 1640 if (m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP) 1641 { 1642 try 1643 { 1644 waitForReset(contextReset); 1645 1646 const glw::GLenum status = gl.getGraphicsResetStatus(); 1647 1648 if (status == GL_NO_ERROR) 1649 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Context was NOT lost"); 1650 else 1651 { 1652 m_testCtx.getLog() << tcu::TestLog::Message << "glGetGraphicsResetStatus() returned " << glu::getGraphicsResetStatusStr(status) << tcu::TestLog::EndMessage; 1653 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was lost"); 1654 } 1655 } 1656 catch (const glu::Error& error) 1657 { 1658 if (error.getError() == GL_CONTEXT_LOST) 1659 passAndLog(contextReset); 1660 else 1661 { 1662 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1663 1664 m_testCtx.getLog() << tcu::TestLog::Message 1665 << "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]" 1666 << tcu::TestLog::EndMessage; 1667 } 1668 } 1669 } 1670 else if (m_params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB || m_params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB) 1671 { 1672 try 1673 { 1674 waitForReset(contextReset); 1675 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was NOT lost. Test skipped"); 1676 } 1677 catch (const glu::Error& error) 1678 { 1679 if (error.getError() == GL_CONTEXT_LOST) 1680 { 1681 if (isContextRobust) 1682 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "No context reset should of occurred GL_CONTEXT_ROBUST_ACCESS == TRUE"); 1683 else 1684 passAndLog(contextReset); 1685 } 1686 else if (isContextRobust) 1687 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unknown error."); 1688 else 1689 { 1690 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Warning: glGetError() returned wrong value. Expected GL_CONTEXT_LOST"); 1691 1692 m_testCtx.getLog() << tcu::TestLog::Message 1693 << "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]" 1694 << tcu::TestLog::EndMessage; 1695 } 1696 } 1697 } 1698 else 1699 DE_FATAL("Unknown context reset type"); 1700 } 1701 1702 class BasicResetCase : public ContextResetCase 1703 { 1704 public: 1705 1706 BasicResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params) 1707 : ContextResetCase (eglTestCtx, name, description, params) {} 1708 1709 virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset) 1710 { 1711 m_testCtx.getLog() << tcu::TestLog::Message 1712 << "Check the graphics reset status returned by glGetGraphicsResetStatus() equals " 1713 << "GL_GUILTY_CONTEXT_RESET after a context reset\n\n" 1714 << tcu::TestLog::EndMessage; 1715 1716 contextReset->setup(); 1717 contextReset->draw(); 1718 } 1719 1720 virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset) 1721 { 1722 contextReset->teardown(); 1723 contextReset->finish(); 1724 } 1725 1726 virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset) 1727 { 1728 const glw::GLint status = contextReset->getGraphicsResetStatus(); 1729 1730 if (status == GL_NO_ERROR) 1731 { 1732 m_testCtx.getLog() << tcu::TestLog::Message 1733 << "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getGraphicsResetStatusStr(status) << ", expected " << glu::getGraphicsResetStatusStr(GL_GUILTY_CONTEXT_RESET) << "]" 1734 << tcu::TestLog::EndMessage; 1735 1736 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1737 } 1738 else 1739 { 1740 if (contextReset->getError() != GL_NO_ERROR) 1741 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error flag not reset after calling getGraphicsResetStatus()"); 1742 else 1743 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1744 } 1745 } 1746 }; 1747 1748 class SyncObjectResetCase : public ContextResetCase 1749 { 1750 public: 1751 SyncObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params) 1752 : ContextResetCase (eglTestCtx, name, description, params) {} 1753 1754 virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset) 1755 { 1756 m_testCtx.getLog() << tcu::TestLog::Message 1757 << "Check the status of a sync object after a context reset returned by glGetSynciv() equals GL_SIGNALED\n\n" 1758 << tcu::TestLog::EndMessage; 1759 1760 contextReset->setup(); 1761 contextReset->draw(); 1762 } 1763 1764 virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset) 1765 { 1766 contextReset->createSyncObject(); 1767 contextReset->teardown(); 1768 contextReset->finish(); 1769 } 1770 1771 virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset) 1772 { 1773 const glw::GLint status = contextReset->getSyncStatus(); 1774 if (status != GL_SIGNALED) 1775 { 1776 m_testCtx.getLog() << tcu::TestLog::Message 1777 << "Test failed! glGetSynciv() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_SIGNALED) << "]" 1778 << tcu::TestLog::EndMessage; 1779 1780 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1781 } 1782 else 1783 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1784 } 1785 }; 1786 1787 class QueryObjectResetCase : public ContextResetCase 1788 { 1789 public: 1790 QueryObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params) 1791 : ContextResetCase (eglTestCtx, name, description, params) {} 1792 1793 virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset) 1794 { 1795 m_testCtx.getLog() << tcu::TestLog::Message 1796 << "Check the status of a query object after a context reset returned by glGetQueryObjectuiv() equals GL_TRUE\n\n" 1797 << tcu::TestLog::EndMessage; 1798 1799 contextReset->setup(); 1800 contextReset->beginQuery(); 1801 contextReset->draw(); 1802 } 1803 1804 virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset) 1805 { 1806 contextReset->endQuery(); 1807 contextReset->teardown(); 1808 contextReset->finish(); 1809 } 1810 1811 virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset) 1812 { 1813 const glw::GLuint queryReady = contextReset->getQueryAvailability(); 1814 if (queryReady != GL_TRUE) 1815 { 1816 m_testCtx.getLog() << tcu::TestLog::Message 1817 << "Test failed! glGetQueryObjectuiv() returned wrong value [" << glu::getErrorStr(queryReady) << ", expected " << glu::getErrorStr(GL_TRUE) << "]" 1818 << tcu::TestLog::EndMessage; 1819 1820 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1821 } 1822 else 1823 { 1824 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1825 } 1826 } 1827 }; 1828 1829 class InvalidShareContextCase : public RobustnessTestCase 1830 { 1831 public: 1832 InvalidShareContextCase (EglTestContext& eglTestCtx, const char* name, const char* description) 1833 : RobustnessTestCase (eglTestCtx, name, description) {} 1834 1835 TestCase::IterateResult iterate (void) 1836 { 1837 TestLog& log = m_testCtx.getLog(); 1838 const Library& egl = m_eglTestCtx.getLibrary(); 1839 bool isOk = true; 1840 1841 log << tcu::TestLog::Message 1842 << "EGL_BAD_MATCH is generated if reset notification strategies do not match when creating shared contexts\n\n" 1843 << tcu::TestLog::EndMessage; 1844 1845 const EGLint attribListA[] = 1846 { 1847 EGL_CONTEXT_CLIENT_VERSION, 3, 1848 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1849 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, 1850 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION, 1851 EGL_NONE 1852 }; 1853 1854 const EGLint attribListB[] = 1855 { 1856 EGL_CONTEXT_CLIENT_VERSION, 3, 1857 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1858 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, 1859 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET, 1860 EGL_NONE 1861 }; 1862 1863 checkRequiredEGLExtensions(attribListA); 1864 1865 log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage; 1866 RenderingContext contextA(m_eglTestCtx, attribListA, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 1867 1868 log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage; 1869 logAttribList(m_eglTestCtx, attribListB); 1870 1871 EGLContext contextB = egl.createContext(m_eglDisplay, m_eglConfig, contextA.getContext(), attribListB); 1872 1873 const EGLenum error = egl.getError(); 1874 if (error != EGL_BAD_MATCH) 1875 { 1876 log << TestLog::Message 1877 << "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_MATCH) << "]" 1878 << TestLog::EndMessage; 1879 1880 isOk = false; 1881 } 1882 1883 if (contextB != EGL_NO_CONTEXT) 1884 egl.destroyContext(m_eglDisplay, contextB); 1885 1886 if (isOk) 1887 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1888 else 1889 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1890 1891 return STOP; 1892 } 1893 }; 1894 1895 class SharedContextResetCase : public RobustnessTestCase 1896 { 1897 public: 1898 SharedContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params) 1899 : RobustnessTestCase (eglTestCtx, name, description, params) {} 1900 1901 TestCase::IterateResult iterate (void) 1902 { 1903 TestLog& log = m_testCtx.getLog(); 1904 1905 log << tcu::TestLog::Message 1906 << "A reset in one context will result in a reset in all other contexts in its share group\n\n" 1907 << tcu::TestLog::EndMessage; 1908 1909 // Create two share contexts with the same reset notification strategies 1910 const EGLint attribListShared[] = 1911 { 1912 EGL_CONTEXT_CLIENT_VERSION, 3, 1913 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1914 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, 1915 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET, 1916 EGL_NONE 1917 }; 1918 1919 checkRequiredEGLExtensions(attribListShared); 1920 1921 log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage; 1922 RenderingContext contextA(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 1923 1924 log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage; 1925 RenderingContext contextB(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, contextA.getContext()); 1926 1927 contextA.makeCurrent(m_eglSurface); 1928 1929 glw::Functions gl; 1930 contextA.initGLFunctions(&gl, paramsToApiType(m_params)); 1931 checkGLSupportForParams(gl, m_params); 1932 1933 DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP); 1934 de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType())); 1935 1936 contextReset->setup(); 1937 contextReset->draw(); 1938 1939 try 1940 { 1941 contextReset->teardown(); 1942 contextReset->finish(); 1943 } 1944 catch (const glu::Error& error) 1945 { 1946 if (error.getError() == GL_CONTEXT_LOST) 1947 { 1948 contextB.makeCurrent(m_eglSurface); 1949 1950 gl.getString(GL_VERSION); // arbitrary gl call 1951 1952 if (gl.getError() != GL_CONTEXT_LOST) 1953 { 1954 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context B"); 1955 return STOP; 1956 } 1957 } 1958 else 1959 { 1960 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A"); 1961 return STOP; 1962 } 1963 } 1964 1965 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1966 return STOP; 1967 } 1968 }; 1969 1970 class InvalidContextCase : public RobustnessTestCase 1971 { 1972 public: 1973 InvalidContextCase (EglTestContext& eglTestCtx, const char* name, const char* description) 1974 : RobustnessTestCase (eglTestCtx, name, description) {} 1975 1976 TestCase::IterateResult iterate (void) 1977 { 1978 const Library& egl = m_eglTestCtx.getLibrary(); 1979 TestLog& log = m_testCtx.getLog(); 1980 bool isOk = true; 1981 1982 log << tcu::TestLog::Message 1983 << "EGL_BAD_ATTRIBUTE is generated if EXT_create_context_robustness is NOT supported but EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT is specified\n\n" 1984 << tcu::TestLog::EndMessage; 1985 1986 const EGLint attribList[] = 1987 { 1988 EGL_CONTEXT_CLIENT_VERSION, 3, 1989 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 1990 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET, 1991 EGL_NONE 1992 }; 1993 1994 if (eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_create_context_robustness")) 1995 { 1996 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL_EXT_create_context_robustness to be unsupported"); 1997 return STOP; 1998 } 1999 2000 logAttribList(m_eglTestCtx, attribList); 2001 EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList); 2002 2003 const EGLenum error = egl.getError(); 2004 if (error != EGL_BAD_ATTRIBUTE) 2005 { 2006 log << TestLog::Message 2007 << "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]" 2008 << TestLog::EndMessage; 2009 2010 isOk = false; 2011 } 2012 2013 if (context != EGL_NO_CONTEXT) 2014 egl.destroyContext(m_eglDisplay, context); 2015 2016 if (isOk) 2017 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2018 else 2019 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2020 2021 return STOP; 2022 } 2023 }; 2024 2025 class RecoverFromResetCase : public RobustnessTestCase 2026 { 2027 public: 2028 RecoverFromResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params) 2029 : RobustnessTestCase (eglTestCtx, name, description, params) {} 2030 2031 TestCase::IterateResult iterate (void) 2032 { 2033 TestLog& log = m_testCtx.getLog(); 2034 2035 log << tcu::TestLog::Message 2036 << "Provoke a context reset and wait for glGetGraphicsResetStatus() to return NO_ERROR_KHR.\n" 2037 << "Destroy the old context and successfully create a new context.\n\n" 2038 << tcu::TestLog::EndMessage; 2039 2040 const EGLint attribList[] = 2041 { 2042 EGL_CONTEXT_CLIENT_VERSION, 3, 2043 EGL_CONTEXT_MINOR_VERSION_KHR, 0, 2044 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, 2045 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET, 2046 EGL_NONE 2047 }; 2048 2049 checkRequiredEGLExtensions(attribList); 2050 2051 log << tcu::TestLog::Message << "Create context A" << tcu::TestLog::EndMessage; 2052 RenderingContext contextA(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 2053 contextA.makeCurrent(m_eglSurface); 2054 2055 glw::Functions gl; 2056 contextA.initGLFunctions(&gl, paramsToApiType(m_params)); 2057 checkGLSupportForParams(gl, m_params); 2058 2059 DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP); 2060 de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType())); 2061 2062 contextReset->setup(); 2063 contextReset->draw(); 2064 2065 try 2066 { 2067 contextReset->teardown(); 2068 contextReset->finish(); 2069 } 2070 catch (const glu::Error& error) 2071 { 2072 if (error.getError() == GL_CONTEXT_LOST) 2073 { 2074 const glw::GLint status = gl.getGraphicsResetStatus(); 2075 if (status == GL_NO_ERROR) 2076 { 2077 log << tcu::TestLog::Message 2078 << "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_GUILTY_CONTEXT_RESET) << "]" 2079 << tcu::TestLog::EndMessage; 2080 2081 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2082 return STOP; 2083 } 2084 2085 const int sleepTimeMs = 1000; // (1 second) 2086 int timeout = sleepTimeMs * 10; // (10 seconds) 2087 int reset_status = -1; 2088 2089 // wait for context to reset 2090 while ((reset_status = gl.getGraphicsResetStatus() != GL_NO_ERROR) && timeout > 0) 2091 { 2092 deSleep(sleepTimeMs); 2093 timeout -= sleepTimeMs; 2094 } 2095 2096 if (reset_status != GL_NO_ERROR) 2097 { 2098 log << tcu::TestLog::Message 2099 << "Test failed! Context did not reset. glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(reset_status) << ", expected " << glu::getErrorStr(GL_NO_ERROR) << "]" 2100 << tcu::TestLog::EndMessage; 2101 2102 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2103 return STOP; 2104 } 2105 } 2106 else 2107 { 2108 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A"); 2109 return STOP; 2110 } 2111 } 2112 2113 try 2114 { 2115 log << tcu::TestLog::Message << "Create context B" << tcu::TestLog::EndMessage; 2116 RenderingContext contextB(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT); 2117 } 2118 catch (const glu::Error&) 2119 { 2120 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! Could not create new context. glGetError() returned wrong value. Expected GL_NO_ERROR"); 2121 return STOP; 2122 } 2123 2124 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2125 return STOP; 2126 } 2127 }; 2128 2129 } // anonymous 2130 2131 // Note: Tests limited to openGLES 3.1 contexts only 2132 TestCaseGroup* createRobustnessTests (EglTestContext& eglTestCtx) 2133 { 2134 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "robustness", "KHR_robustness tests")); 2135 2136 tcu::TestCaseGroup* const contextCreationTestGroup = new TestCaseGroup(eglTestCtx, "create_context", "Test valid context_creation attributes"); 2137 tcu::TestCaseGroup* const contextResetTestGroup = new TestCaseGroup(eglTestCtx, "reset_context", "Test context resets scenarios"); 2138 tcu::TestCaseGroup* const negativeContextTestGroup = new TestCaseGroup(eglTestCtx, "negative_context", "Test invalid context creation attributes"); 2139 2140 tcu::TestCaseGroup* const shadersTestGroup = new TestCaseGroup(eglTestCtx, "shaders", "Shader specific context reset tests"); 2141 tcu::TestCaseGroup* const fixedFunctionTestGroup = new TestCaseGroup(eglTestCtx, "fixed_function_pipeline", "Fixed function pipeline context reset tests with robust context"); 2142 tcu::TestCaseGroup* const fixedFunctionNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "fixed_function_pipeline_non_robust", "Fixed function pipeline context reset tests with non-robust context"); 2143 2144 tcu::TestCaseGroup* const infiniteLoopTestGroup = new TestCaseGroup(eglTestCtx, "infinite_loop", "Infinite loop scenarios"); 2145 tcu::TestCaseGroup* const outOfBoundsTestGroup = new TestCaseGroup(eglTestCtx, "out_of_bounds", "Out of bounds access scenarios with robust context"); 2146 2147 tcu::TestCaseGroup* const outOfBoundsNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "out_of_bounds_non_robust", "Out of bounds access scenarios with non-robust context"); 2148 2149 const string resetScenarioDescription = "query error states and reset notifications"; 2150 const string syncScenarioDescription = "query sync status with getSynciv()"; 2151 const string queryScenarioDescription = "check availability of query result with getQueryObjectiv()"; 2152 const string sharedScenarioDescription = "check reset notification is propagated to shared context"; 2153 const string recoverScenarioDescription = "delete the old context and create a new one"; 2154 2155 // infinite loop test cases 2156 { 2157 tcu::TestCaseGroup* const infiniteLoopResetTestGroup = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred"); 2158 tcu::TestCaseGroup* const infiniteLoopSyncTestGroup = new TestCaseGroup(eglTestCtx, "sync_status", "Tests that query the sync status after a context reset has occurred"); 2159 tcu::TestCaseGroup* const infiniteLoopQueryTestGroup = new TestCaseGroup(eglTestCtx, "query_status", "Tests that query the state of a query object after a context reset has occurred"); 2160 tcu::TestCaseGroup* const infiniteLoopSharedTestGroup = new TestCaseGroup(eglTestCtx, "shared_context_status", "Tests that query the state of a shared context after a reset has occurred"); 2161 tcu::TestCaseGroup* const infiniteLoopRecoverTestGroup = new TestCaseGroup(eglTestCtx, "recover_from_reset", "Tests that attempt to create a new context after a context has occurred"); 2162 2163 static const RobustnessTestCase::Params s_infiniteLoopCases[] = 2164 { 2165 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_VERT), 2166 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ", CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_FRAG), 2167 RobustnessTestCase::Params("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_VERT_AND_FRAG), 2168 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_COMPUTE), 2169 }; 2170 2171 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_infiniteLoopCases); ++testNdx) 2172 { 2173 const RobustnessTestCase::Params& test = s_infiniteLoopCases[testNdx]; 2174 infiniteLoopResetTestGroup->addChild (new BasicResetCase (eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2175 infiniteLoopSyncTestGroup->addChild (new SyncObjectResetCase (eglTestCtx, test.getName().c_str(), (test.getDescription() + syncScenarioDescription).c_str(), test)); 2176 infiniteLoopQueryTestGroup->addChild (new QueryObjectResetCase (eglTestCtx, test.getName().c_str(), (test.getDescription() + queryScenarioDescription).c_str(), test)); 2177 infiniteLoopSharedTestGroup->addChild (new SharedContextResetCase (eglTestCtx, test.getName().c_str(), (test.getDescription() + sharedScenarioDescription).c_str(), test)); 2178 infiniteLoopRecoverTestGroup->addChild (new RecoverFromResetCase (eglTestCtx, test.getName().c_str(), (test.getDescription() + recoverScenarioDescription).c_str(), test)); 2179 } 2180 2181 infiniteLoopTestGroup->addChild(infiniteLoopResetTestGroup); 2182 infiniteLoopTestGroup->addChild(infiniteLoopSyncTestGroup); 2183 infiniteLoopTestGroup->addChild(infiniteLoopQueryTestGroup); 2184 infiniteLoopTestGroup->addChild(infiniteLoopSharedTestGroup); 2185 infiniteLoopTestGroup->addChild(infiniteLoopRecoverTestGroup); 2186 } 2187 2188 // out-of-bounds test cases 2189 { 2190 // robust context 2191 tcu::TestCaseGroup* const uboReadArrayResetTestGroup = new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses"); 2192 tcu::TestCaseGroup* const uboWriteArrayResetTestGroup = new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses"); 2193 tcu::TestCaseGroup* const ssboWriteArrayResetTestGroup = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses"); 2194 tcu::TestCaseGroup* const ssboReadArrayResetTestGroup = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses"); 2195 tcu::TestCaseGroup* const localWriteArrayResetTestGroup = new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses"); 2196 tcu::TestCaseGroup* const localReadArrayResetTestGroup = new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses"); 2197 2198 // non-robust context (internal use only) 2199 tcu::TestCaseGroup* const uboReadArrayResetNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses"); 2200 tcu::TestCaseGroup* const uboWriteArrayResetNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses"); 2201 tcu::TestCaseGroup* const ssboWriteArrayResetNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses"); 2202 tcu::TestCaseGroup* const ssboReadArrayResetNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses"); 2203 tcu::TestCaseGroup* const localWriteArrayResetNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses"); 2204 tcu::TestCaseGroup* const localReadArrayResetNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses"); 2205 2206 static const RobustnessTestCase::Params s_outOfBoundReadCases[] = 2207 { 2208 // ubo read only 2209 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO, READWRITETYPE_READ), 2210 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_UBO, READWRITETYPE_READ), 2211 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_READ), 2212 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO, READWRITETYPE_READ), 2213 2214 // ssbo read only 2215 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2216 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2217 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2218 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2219 2220 // local array read only 2221 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2222 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2223 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2224 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2225 2226 // ubo read only (non-robust) 2227 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO, READWRITETYPE_READ), 2228 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_UBO, READWRITETYPE_READ), 2229 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_READ), 2230 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO, READWRITETYPE_READ), 2231 2232 // ssbo read only (non-robust) 2233 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2234 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2235 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2236 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO, READWRITETYPE_READ), 2237 2238 // local array read only (non-robust) 2239 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2240 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2241 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2242 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ), 2243 }; 2244 2245 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundReadCases); ++testNdx) 2246 { 2247 const RobustnessTestCase::Params& test = s_outOfBoundReadCases[testNdx]; 2248 2249 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE) 2250 uboReadArrayResetTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2251 2252 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE) 2253 uboReadArrayResetNonRobustTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2254 2255 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE) 2256 ssboReadArrayResetTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2257 2258 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE) 2259 ssboReadArrayResetNonRobustTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2260 2261 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE) 2262 localReadArrayResetTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2263 2264 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE) 2265 localReadArrayResetNonRobustTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2266 } 2267 2268 static const RobustnessTestCase::Params s_outOfBoundWriteCases[] = 2269 { 2270 // ubo write only 2271 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2272 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2273 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2274 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2275 2276 // ssbo write only 2277 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2278 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2279 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2280 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2281 2282 // local array write only 2283 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2284 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2285 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2286 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2287 2288 // ubo write only (non-robust) 2289 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2290 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2291 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2292 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO, READWRITETYPE_WRITE), 2293 2294 // ssbo write only (non-robust) 2295 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2296 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2297 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2298 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO, READWRITETYPE_WRITE), 2299 2300 // local array write only (non-robust) 2301 RobustnessTestCase::Params ("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2302 RobustnessTestCase::Params ("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2303 RobustnessTestCase::Params ("vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2304 RobustnessTestCase::Params ("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE), 2305 }; 2306 2307 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundWriteCases); ++testNdx) 2308 { 2309 const RobustnessTestCase::Params& test = s_outOfBoundWriteCases[testNdx]; 2310 2311 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE) 2312 uboWriteArrayResetTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2313 2314 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE) 2315 uboWriteArrayResetNonRobustTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2316 2317 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE) 2318 ssboWriteArrayResetTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2319 2320 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE) 2321 ssboWriteArrayResetNonRobustTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2322 2323 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE) 2324 localWriteArrayResetTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2325 2326 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE) 2327 localWriteArrayResetNonRobustTestGroup->addChild (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test)); 2328 } 2329 2330 // robust Context 2331 tcu::TestCaseGroup* const outOfBoundsResetReadAccessTestGroup = new TestCaseGroup(eglTestCtx, "reads", "Out of bounds read accesses"); 2332 tcu::TestCaseGroup* const outOfBoundsResetWriteAccessTestGroup = new TestCaseGroup(eglTestCtx, "writes", "Out of bounds write accesses"); 2333 2334 outOfBoundsResetReadAccessTestGroup->addChild(uboReadArrayResetTestGroup); 2335 outOfBoundsResetReadAccessTestGroup->addChild(ssboReadArrayResetTestGroup); 2336 outOfBoundsResetReadAccessTestGroup->addChild(localReadArrayResetTestGroup); 2337 2338 outOfBoundsResetWriteAccessTestGroup->addChild(uboWriteArrayResetTestGroup); 2339 outOfBoundsResetWriteAccessTestGroup->addChild(ssboWriteArrayResetTestGroup); 2340 outOfBoundsResetWriteAccessTestGroup->addChild(localWriteArrayResetTestGroup); 2341 2342 tcu::TestCaseGroup* const outOfBoundsResetTestGroup = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred"); 2343 2344 outOfBoundsResetTestGroup->addChild(outOfBoundsResetReadAccessTestGroup); 2345 outOfBoundsResetTestGroup->addChild(outOfBoundsResetWriteAccessTestGroup); 2346 2347 outOfBoundsTestGroup->addChild(outOfBoundsResetTestGroup); 2348 2349 // non-robust Context (internal use only) 2350 tcu::TestCaseGroup* const outOfBoundsResetReadAccessNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "reads", "Out of bounds read accesses"); 2351 tcu::TestCaseGroup* const outOfBoundsResetWriteAccessNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "writes", "Out of bounds write accesses"); 2352 2353 outOfBoundsResetReadAccessNonRobustTestGroup->addChild(uboReadArrayResetNonRobustTestGroup); 2354 outOfBoundsResetReadAccessNonRobustTestGroup->addChild(ssboReadArrayResetNonRobustTestGroup); 2355 outOfBoundsResetReadAccessNonRobustTestGroup->addChild(localReadArrayResetNonRobustTestGroup); 2356 2357 outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(uboWriteArrayResetNonRobustTestGroup); 2358 outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(ssboWriteArrayResetNonRobustTestGroup); 2359 outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(localWriteArrayResetNonRobustTestGroup); 2360 2361 tcu::TestCaseGroup* const outOfBoundsResetNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred"); 2362 2363 outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetReadAccessNonRobustTestGroup); 2364 outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetWriteAccessNonRobustTestGroup); 2365 2366 outOfBoundsNonRobustTestGroup->addChild(outOfBoundsResetNonRobustTestGroup); 2367 } 2368 2369 // fixed function test cases 2370 { 2371 // robust context 2372 tcu::TestCaseGroup* const fixedFunctionResetStatusTestGroup = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred"); 2373 2374 // non-robust context (internal use only) 2375 tcu::TestCaseGroup* const fixedFunctionResetStatusNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred"); 2376 2377 static const RobustnessTestCase::Params s_fixedFunctionPipelineCases[] = 2378 { 2379 RobustnessTestCase::Params( "index_buffer_out_of_bounds", "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES), 2380 RobustnessTestCase::Params( "vertex_buffer_out_of_bounds", "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES), 2381 2382 RobustnessTestCase::Params( "index_buffer_out_of_bounds", "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES), 2383 RobustnessTestCase::Params( "vertex_buffer_out_of_bounds", "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES), 2384 }; 2385 2386 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_fixedFunctionPipelineCases); ++testNdx) 2387 { 2388 const RobustnessTestCase::Params& test = s_fixedFunctionPipelineCases[testNdx]; 2389 if (test.getRobustAccessType() == ROBUSTACCESS_TRUE) 2390 fixedFunctionResetStatusTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test)); 2391 else 2392 fixedFunctionResetStatusNonRobustTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test)); 2393 } 2394 2395 fixedFunctionTestGroup->addChild(fixedFunctionResetStatusTestGroup); 2396 fixedFunctionNonRobustTestGroup->addChild(fixedFunctionResetStatusNonRobustTestGroup); 2397 } 2398 2399 // context creation query cases 2400 { 2401 contextCreationTestGroup->addChild(new QueryRobustAccessCase (eglTestCtx, "query_robust_access", "Query robust access after successfully creating a robust context")); 2402 contextCreationTestGroup->addChild(new NoResetNotificationCase (eglTestCtx, "no_reset_notification", "Query reset notification strategy after specifying GL_NO_RESET_NOTIFICATION")); 2403 contextCreationTestGroup->addChild(new LoseContextOnResetCase (eglTestCtx, "lose_context_on_reset", "Query reset notification strategy after specifying GL_LOSE_CONTEXT_ON_RESET")); 2404 } 2405 2406 // invalid context creation cases 2407 { 2408 negativeContextTestGroup->addChild(new InvalidContextCase (eglTestCtx, "invalid_robust_context_creation", "Create a non-robust context but specify a reset notification strategy")); 2409 negativeContextTestGroup->addChild(new InvalidShareContextCase (eglTestCtx, "invalid_robust_shared_context_creation", "Create a context share group with conflicting reset notification strategies")); 2410 } 2411 2412 shadersTestGroup->addChild(infiniteLoopTestGroup); 2413 shadersTestGroup->addChild(outOfBoundsTestGroup); 2414 shadersTestGroup->addChild(outOfBoundsNonRobustTestGroup); 2415 2416 contextResetTestGroup->addChild(shadersTestGroup); 2417 contextResetTestGroup->addChild(fixedFunctionTestGroup); 2418 contextResetTestGroup->addChild(fixedFunctionNonRobustTestGroup); 2419 2420 group->addChild(contextCreationTestGroup); 2421 group->addChild(contextResetTestGroup); 2422 group->addChild(negativeContextTestGroup); 2423 2424 return group.release(); 2425 } 2426 2427 } // egl 2428 } // deqp 2429