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