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