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